在实例化对象之前可以引用对象的成员吗?

发布于 2024-10-16 04:14:39 字数 330 浏览 0 评论 0原文

这就是我想要做的(警告:前面的 Scala 极其损坏):

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

显然,这根本行不通,但我正在寻找一种模式,允许我引用以下成员:抽象中的实例,然后在稍后的某个时刻,访问实际实例上的该成员。

如果这是 Java,我会使用反射,但反射很糟糕,我希望 Scala 能有一个更好的选择,因为它比 Java 糟糕得多。

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 sucks and I am hoping Scala, which sucks so much less than Java, would have a better alternative.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒儿 2024-10-23 04:14:39

所以:

  • Scala 的属性是作为一对方法实现的。对于 var m,getter 方法将被命名为 m,setter 方法将被命名为 m_=
  • 方法可以自动提升为函数
  • 函数可以是作为一流值传递

从这里开始:

class M {
  var m = 0
}

val x = new M

xm 当前为 0,让我们更改它...
下面的方法采用 Function 作为参数,并使用值 4 调用该函数:

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

并使用它:

callWithFour(x.m_=)

其中 x.m_=4 的 setter 方法。实例 x 上的 code>m 属性

xm 现在等于 4。

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.

时光无声 2024-10-23 04:14:39

虽然结构类型是一种替代方案,但它们在内部使用反射。

您实际上想要做的是调用某个属性的 setter,以便您可以将其概括为函数调用:

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

此方法采用两个参数:X 的某个实例和一个函数 f > 将您的 X 转换为从 Int 到某种类型 Y 的函数(在您的情况下,这将是 Unit )。

使用 或 在更短但可读性较差的变体中调用它:

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

现在,您可以使用生成的 setter m_=

applyWith4(em)(_ m_=)

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_=)
橘虞初梦 2024-10-23 04:14:39

您可以使用结构类型,这样您就不会依赖于特定类型(尽管失去了一些灵活性,无法传递要更新的属性名称):

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文