开发者

Can refer to a member of an object before I've instantiated the object?

Here's what I want to do (warning: extremely broken Scala ahead):

def assignToFour[X](x : X, y : Something[X]) =  x.y = 4

class M {
   var m = 0;
}

val em = new M
assignToFour(em, M.m)
em.m == 4

Obviously, that won't work at all, but I'm looking for a pattern that will allow me to refer to an member of an instance in the abstract and then at some later point, access that member on an actual instance.

If this were Java, I would use reflection, but reflection s开发者_StackOverflow社区ucks and I am hoping Scala, which sucks so much less than Java, would have a better alternative.


So:

  • Scala's properties are implemented as a pair of methods. For a var m the getter will be named m and the setter method will be named m_=
  • Methods can be automatically lifted to functions
  • Functions can be passed around as first-class values

Starting here:

class M {
  var m = 0
}

val x = new M

x.m is currently 0, let's change that... Here's a method that takes a Function as its argument, and calls that function with the value 4:

def callWithFour(fn: Int=>Unit) = fn(4)

And using it:

callWithFour(x.m_=)

Where x.m_= is the setter method for the m property on the instance x

x.m is now equal to four.


While structural types are an alternative they use reflection internally.

What you actually want to do is invoke the setter of some property so you can generalize it to a function call:

def applyWith4[X,Y](x: X)(f: X => Int => Y) = f(x)(4)

This method takes two arguments: some instance of X and one function f that turns your X into a function from Int to some type Y (this will be Unit in your case).

Now you can invoke it using

applyWith4(em)(x => x.m = _)

or in a shorter but less readable variant using the generated setter m_=:

applyWith4(em)(_ m_=)


You can use structural types, so you won't depend on a specific type (though lose some flexibility no being able to pass the name of the property to update):

def assignToFour(x:{var y:Int}) = x.y = 4
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜