class A {
def a(): Unit = ()
def b[T](f: A => T): T = f(new A())
def c(): Unit = b { _.a() }
def d(): Boolean = b { w => w.a(); true }
//def e(): Boolean = b { _.a(); true } // does not compile - why not, if c compiles?
}
在上面的类的e()方法中,我认为编译器能够像在c()中一样推断出“_”的类型。但是,对于scala 2.11.7,e()会导致“扩展函数缺少参数类型。为什么?编译器应该能够(=编译器错误)或者编译器在抱怨时是否正确?
答案 0 :(得分:1)
我认为这是因为b { _.a(); true }
由编译器翻译成b { w => { w.a() }; true }
而不是预期的b { w => { w.a(); true } }
。因此,它计算整个表达式并尝试将Boolean
类型的表达式传递给b
而不是A => Boolean
。至少那是我看到的唯一解释,不幸的是我不知道如何检查。编译器的错误似乎在试图说出这一点时非常诚实。
总的来说,您不应该将_
通配符与复杂表达式一起使用。它们仅适用于简单的
我也认为@Felix评论你的问题也是正确的 - 部分问题也是如此。编译器含糊不清:T
可以是Unit
或Boolean
,它只是错误地解决了它。不幸的是,即使您定义b
接受A => Boolean
P.S。通过适当的编译器消息,我的意思是:
Error:(24, 36) type mismatch;
found : Boolean(true)
required: Main.A => Boolean
def e(): Boolean = bb { _.a(); true } // does not compile - why not, if c compiles?
^
答案 1 :(得分:0)
首先,我不认为它是scala编译器的错误。
对于函数d()
,它应该扩展为:
def d(): Boolean = b { w => {w.a(); true} }
不
def d(): Boolean = b { {w => w.a()}; true }
所以这可能会引起一些歧义。
用于函数e()
,因为编译器不知道指定类型的通配符_
。
示例:
scala> def f(s: String): String = s
f: (s: String)String
scala> List("foo", "bar").map(f(_.toUpperCase))
<console>:12: error: missing parameter type for expanded function ((x$1) => x$1.toUpperCase)
scala> List("foo", "bar").map(i => f(i.toUpperCase))
res3: List[String] = List(FOO, BAR)
因为对于无穷无尽的函数,编译器无法推断出通配符_
的类型。
def e(): Boolean = b { _.a(); true }
编译器不知道上面代码中_
的类型。
因为它可以翻译为:
def e(): Boolean = b {{_.a()}; true }
或:
def e(): Boolean = b {{x => x.a()}; true }