代码之家  ›  专栏  ›  技术社区  ›  Moebius

无法用lambda重写scala抽象函数

  •  3
  • Moebius  · 技术社区  · 6 年前

    如果我写:

    trait Aaa { 
      def a(i: Int): Boolean 
    }
    
    class Bbb extends Aaa { 
      def a = (x: Int) => x == 42 
    }
    

    但它无法编译,我得到以下错误:

    override.scala:7: class Bbb needs to be abstract, since method a in trait Aaa of type (i: Int)Boolean is not defined
    class Bbb extends Aaa {
          ^
    Compilation Failed
    

    为什么?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Tim    6 年前

    特点 Aaa 定义 方法 a 但是这个班 Bbb 定义 函数值 . 方法与函数值不同的是scala,因此 在你班上 血脑屏障 不实现 在里面 美国农业协会 . 自从 Aaa.a 没有定义,必须声明类 abstract .

    如果您改为这样做,它将起作用:

    class Bbb extends Aaa {
      def a(x:Int) = x == 42
    }
    

    如果确实需要函数值而不是方法,则需要声明另一个 val 并使用 ETA扩展 这样地:

    class Bbb extends Aaa {
      def a(x:Int) = x == 42
      val b = a _
    }
    

    b 现在可以作为函数参数传递给以下调用: filter 鉴于 不能。

        2
  •  3
  •   Andrey Tyukin    6 年前

    特点 Aaa 规定必须有一种方法 a 有一个类型的参数 Int 和返回类型 Boolean .

    班级 Bbb 有一个方法 没有任何参数和返回类型 (Int => Boolean) ,与 Function1[Int, Boolean] .

    所以,方法 在里面 血脑屏障 参数个数错误,返回类型不同。

    它不应该编译,所以不编译。没问题。


    一般注释:

    def f(x1: T1, ..., xn: Tn): Y = body
    

    不是句法上的糖分

    val f = (x1: T1, ..., xn: Tn): Y => body
    

    前者是方法,后者是类型的值 FunctionN[T1, ..., Tn, Y] . 虽然这两个定义可以在受ML影响的其他一些语言中以相同的方式处理,但在scala中却不是这样。scala区分方法和函数。