6

考虑一下:

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 非常清楚 in 的确切类型,_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)
4

3 回答 3

1

我建议它是 The Good Book 中这个侧边栏或框的扩展,它表达了最小惊喜原则:

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),我们已经定义了适用性的含义。)

于 2012-10-11T20:00:57.440 回答
1

从这个问题来看,听起来他们可以做到,但对于一般情况来说,相对于它所提供的好处来说,它太复杂了。它通常很复杂的原因是重载方法的可能性。如果您还拥有:

def sum (x : Int , y : Double ) = x + y

在范围内,如果没有类型规范,您所指的功能将是模棱两可的。在没有重载的情况下,类型推断可以很容易地弄清楚,但我感觉他们不觉得为这种特定情况提供服务是值得的。

简而言之,这听起来像是一种实践,而不是理论上的限制。

我相信错误消息是通过简单地获取具有适当名称和数量的第一个函数来生成的,在非重载函数的情况下,它给人的印象是它已经完全推理出类型。

于 2012-10-11T19:42:02.383 回答
0

这个问题的答案对 你有启发吗?正如@oxbow_lakes 的回答所证明的那样,这似乎是一个不一致的地方。

于 2012-10-11T19:12:11.713 回答