Scala:使用值字段实现特征方法

Scala: using value field to implement a trait method

我试图在 Scala 中做这样的事情

trait A { 
  def foo(i: Int): Int 
}

class B(val foo: Int => Int = _ + 1) extends A

但有点令人惊讶的是我从编译器那里得到了这个错误:

error: class B needs to be abstract, since method foo in trait A of type (i: Int)Int is not defined
   class B(val foo: Int => Int = _ + 1) extends A

这也没有用,出现同样的错误:

class C extends A { 
  val foo: Int => Int = _ + 1 
}

然而这(显然)有效:

class D(val bar: Int => Int = _ + 1) extends A { 
  def foo(i: Int): Int = bar(i) 
}

scala> (new D).foo(5)
res1: Int = 6

所以问题是,为什么 Scala 对待 def foo(i: Int): Int = ... 的方式不同于 val foo: Int => Int = ...

因为trait:中定义的def foo(i: Int): Int是一个整数作为输入,returns一个整数作为输出的函数.

其中,val foo: Int => Int = _ + 1定义在class:是一个函数,其中returns是一个函数。这是关键点,你还没有实现一个来自特征的。 class B 中的 foo 正在返回一个函数,返回的函数将一个整数作为输入并在输出中提供一个整数。

最后,我找到了一个非常简单的解决方案来解决我的问题。我所要做的就是把我的特质改成这样:

trait A { def foo: Int => Int }

现在一切如愿:

class B(val foo: Int => Int = _ + 1) extends A

scala> (new B).foo(6)
res3: Int = 7