Function 为什么Scala类方法不是一流公民?

Function 为什么Scala类方法不是一流公民?,function,scala,methods,Function,Scala,Methods,我刚开始使用Scala,正在修改工作表。例如: 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") 以及相应的工作表结果: merp: merp

我刚开始使用Scala,正在修改工作表。例如:

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")
以及相应的工作表结果:

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
工作表结果:

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交互造成的,还是语言设计中的决定
  • 为什么我需要自己滚动,如
    merp3
  • merp4
    也是一个,还是有点像
  • 为什么我的
    etabstractor
    工作?Scala正在悄悄地用
    intCombiner
    取代
    intCombiner吗

  • 理论上的,计算机科学的答案是受欢迎的,因为是指针到任何相关的问题。谢谢

    它与
    etaAbstractor
    一起工作的原因是编译器可以推断出需要函数(而不是函数调用)

    如果我不得不猜测为什么在无法推断函数类型的情况下需要下划线,我认为这是为了改进常见错误类的错误报告(在需要调用的情况下获取函数)。但是,这只是一个猜测


    在JVM中,方法不是对象,而一级函数必须是对象。因此,必须将方法装箱到对象中才能将其转换为函数。

    免责声明:我不是计算机科学家,但我会尝试猜测:

  • 方法是对象的一部分,不存在于对象之外。你不能单独通过这个方法。闭包是封装状态的另一种(等效的?)方式,通过将一个对象方法转换为一个独立的函数(顺便说一句,这只是另一个对象在Scala中使用
    apply()
    method),您正在创建一个闭包。此过程称为eta扩展

  • 你不必这么做。您还可以编写
    valmerp3:(String=>String)=merp

  • 是的,
    merp4
    也是eta扩展


  • Scala的设计和实现与Java/JVM在许多方面的兼容性密切相关——我敢肯定,如果没有这一点,两者之间的差别会很小,但你必须问问Martin(我想他偶尔会访问),或者找到一些早期的impl注释。虽然它们可以很容易地用
    method.
    进行“升级”。Python和JavaScript的方法都是一流的函数,所以#1是“在Scala(和Java中)…。@user2864740在Python中未绑定的方法不能被调用,所以在我看来它不是一流的函数。指定一个绑定方法看起来像是引擎盖下的eta扩展。如果在函数中使用
    this
    ,Javascript也会出现同样的问题,只是在
    this
    的值中会出现
    未定义的
    ,而不是错误。仍然存在的问题是,方法不是一流的值,而是通过名称(或)调用的“定义的表现形式”。维护上下文(或不维护上下文)不会影响他们的公民身份:或者根本的实现差异。非常感谢规范的链接。为了完成Q#1,我推测这是一个语言设计决策,其结果是Scala代码如何被翻译到JVM中。具体地说,方法(是没有值的抽象)可以在编译时最终确定,而
    函数
    (作为对象,其伴随的闭包是动态树结构)只能在运行时创建。要使方法具体化,必须创建
    函数
    对象。这可能会对性能产生影响,因此要求程序员显式地创建该对象而不是误导是一个好的决定。
    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