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

时间:2018-02-06 11:58:09

标签: scala traits

我尝试在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 = ...

2 个答案:

答案 0 :(得分:2)

因为,特征中定义的def foo(i: Int): Int:是一个以整数作为输入的函数,返回一个整数作为输出

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

答案 1 :(得分:0)

最后,我发现了一个令人尴尬的简单解决方案。我所要做的就是将我的特质改为:

trait A { def foo: Int => Int }

现在它按预期工作:

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

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