Scala中函数的等同性是Scala中的函数对象吗?

宇宙人*_*宇宙人 5 scala

我正在读"Scala编程"一书.在本书中,它说"函数文字被编译成一个在运行时实例化时是一个函数值的类".并且它提到"函数值是对象,因此如果您愿意,可以将它们存储在变量中".

所以我尝试检查函数之间的相等性.但我失败了.

  1. 如果函数是Scala中的对象,那么它应该像Scala中的其他对象一样.也许检查功能的平等是没有意义的,所以它是禁用的?

  2. 并将函数编译成Scala中的对象?

cch*_*tep 11

Lambda被编译为匿名类(根据我的记忆,不是案例类).这意味着如果你这样做:

val f1: (String) => String = _ => "F1"
val f2: (String) => String = _ => "F2"
Run Code Online (Sandbox Code Playgroud)

这两个f1f2是的亚型Function1[String,String],但两者是不同匿名类的,所以不能相等.

如果你把它写成:

case class F(res: String) extends ((String) => String) {
  def apply(s: String) = res
}
Run Code Online (Sandbox Code Playgroud)

然后:

val f1: (String) => String = F("A")
val f2: (String) => String = F("A")
f1 == f2 // true
Run Code Online (Sandbox Code Playgroud)

  • 那不是我得到的错误。我得到“错误:方法f1的缺少参数;”和“错误:方法f2的缺少参数;”,这很有意义:您定义了两种方法(函数,函数和方法不是完全不同的) ,`f1`和`f2`都带有一个类型为String的参数,但是您正在* no *参数中调用它们,然后尝试比较调用它们的结果。 (2认同)

Jör*_*tag 6

目前尚不清楚功能的"平等"意味着什么.通常,人们关心的是"这两个函数是否会计算相同的结果?"

然而,这是一个众所周知的不可判定的问题,功能问题.显然,实际证明更复杂,但一个简单的直觉是:如果你能判断两个函数是否相等,那么你可以通过询问"这个函数是否等于while (true) {}?" 来解决停机问题.

因此,我们无法确定两个函数是否计算相同的结果.我们可以做的是,例如,检查它们是否包含完全相同的代码.但这很无聊.只是一些微小的编译器优化或重命名单个变量将使两个直觉上应该相等的函数不相等.

因此,我们采取简单的方法:如果它们相同则两个函数相等,否则它们不相同.