考虑一下:
scala> def sum(x:Int,y:Int) = x+y
sum: (x: Int, y: Int)Int
scala> sum(1,_:String)
<console>:9: error: type mismatch;
found : String
required: Int
sum(1,_:String)
显然,Scala非常了解_
中sum(1,_)
的确切类型,但必须 say sum(1,_:Int)
。为什么?
显然Scala随机(?)选择一个:
scala> def sum(x:Int,y:String) = 1
sum: (x: Int, y: String)Int
scala> def sum(x:Int,y:Double) = 1
sum: (x: Int, y: Double)Int
scala> class Ashkan
defined class Ashkan
scala> sum(1,_:Ashkan)
<console>:10: error: type mismatch;
found : Ashkan
required: Double
sum(1,_:Ashkan)
答案 0 :(得分:1)
从这个issue来看,听起来他们可以做到这一点,但对于一般情况来说,它相对于它提供的好处来说太复杂了。一般情况下复杂的原因是重载方法的可能性。如果您还有:
def sum (x : Int , y : Double ) = x + y
在范围内,如果没有类型规范,你的意思是不明确的。在没有超载的情况下,类型推断很容易解决,但我觉得他们觉得为特定情况提供它是不值得的。
简而言之,听起来它是实用的,而不是理论上的限制。
我相信错误消息是通过简单地使用适当的名称和arity抓取第一个函数生成的,在非重载函数的情况下会给人一种完全推理出类型的印象。
答案 1 :(得分:1)
我建议它是“好书”中这个侧栏或盒子的延伸,它表达了最低惊喜原则:
http://www.artima.com/pins1ed/functions-and-closures.html#8.7
或者让我们不要把它称之为“最少的惊喜”,而是两个惊喜中的较小者。
考虑以下情况,您要求编译器在两个继承的函数之间进行选择。如果适用正常的重载规则,它将选择子类中定义的方法。但这是一个好政策吗?
scala> class Foo {
| def f(x: Int, y: Int) = x + y
| }
defined class Foo
scala> class Bar extends Foo {
| def f(x: Int, y: String) = x + y.toInt
| }
defined class Bar
scala> class Baz extends Bar {
| val f = super.f(1, _) // overloading says f(Int,String), did you mean it?
| }
在面向对象的世界中,有太多方法让自己感到惊讶,因此需要缴纳一小笔税。理智税。
(请注意,在此示例中,可能会重载分辨率,但要求您指定f(1, _: MyWhatever)
,我们已经定义了适用性的含义。)
答案 2 :(得分:0)
this question的答案是否为你揭开了它的光芒?它似乎是一种不一致,正如@oxbow_lakes'answer所示。