为什么斯卡拉课程方法不是一流的公民? [英] Why are Scala class methods not first-class citizens?
问题描述
我刚刚开始Scala,并且正在修改工作表。例如:
I've just started Scala and am tinkering in worksheets. For example:
def merp(str: String) : String = s"Merrrrrrrp $str"
val merp2 = (str: String) => s"Merrrrrrrp $str"
val merp3 = (str: String) => merp(str)
val merp4 = merp _
merp("rjkghleghe")
merp4("rjkghleghe")
以及相应的工作表结果:
And the corresponding worksheet results:
merp: merp[](val str: String) => String
merp2: String => String = <function1>
merp3: String => String = <function1>
merp4: String => String = <function1>
res0: String = Merrrrrrrp rjkghleghe
res1: String = Merrrrrrrp rjkghleghe
,例如, val merp5 = merp
会产生一个错误,因为显然方法不能以函数的方式作为值。但我仍然可以将方法作为参数传递。我在下面的代码片段中演示了这一点,它改编自类似的SO问题:
$ b
Saying, for example, val merp5 = merp
produces an error, because apparently methods cannot be values the way functions can. But I can still pass methods as arguments. I demonstrate this in the following code snippet, adapted from a similar SO question:
def intCombiner(a: Int, b: Int) : String = s"herrrrrrp $a derrrrrrp $b"
def etaAbstractor[A, B](combineFoo: (A, B) ⇒ String, a: A, b: B) = combineFoo(a, b)
etaAbstractor(intCombiner, 15, 16)
工作表结果:
worksheet result:
intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16
- 方法 - 不是首要的限制,可能是由Scala的JVM交互强加的,还是它在语言设计中的决定?
- 为什么我需要推出自己的 eta抽象,如
merp3
? > eta抽象,还是有点类似? - 为什么我的
etaAbstractor
工作? Scala正在悄悄地将intCombiner
替换为intCombiner _
?
- Is methods-not-being-first-class a limitation, perhaps imposed by Scala's JVM interaction, or is it a decision in the language's design?
- Why do I need to roll my own eta abstractions, as in
merp3
? - Is
merp4
also an eta abstraction, or is it something sneakily similar? - Why does my
etaAbstractor
work? Is Scala quietly replacingintCombiner
withintCombiner _
?
欢迎理论,计算机科学的答案,以及指向语言规范。谢谢!
Theoretical, computer sciencey answers are welcome, as are pointers to any relevant points in the language specification. Thanks!
推荐答案
免责声明:我不是计算机科学家,但我会尝试猜测:
Disclaimer: I'm not a computer scientist, but I will try to guess:
-
方法是对象的一部分,不存在于其外部。你不能单独传递方法。 Closure是封装状态的另一种(等价的)方式,通过将对象方法转换为独立函数(这是另一个在Scala中使用
apply()
方法的对象) )你正在创建一个闭包。这个过程被称为eta-expansion。 §3.3.1, §6.26.5
Method is a part of an object and doesn't exist outside of it. You can't pass method alone. Closure is another (equivalent?) way of encapsulating state, by converting an object method to a standalone function (which is by the way just another object with
apply()
method in Scala) you are creating a closure. This process is known as eta-expansion. §3.3.1, §6.26.5
您不必这样做。您也可以编写 val merp3:(String => String)= merp
。 §6.26.5
You don't have to. You can also write val merp3 : (String => String) = merp
. §6.26.5
是的, merp4
也是eta-expansion。 §6.7
Yes, merp4
is eta-expansion too. §6.7
这篇关于为什么斯卡拉课程方法不是一流的公民?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!