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 はランダムに (?) 1 つを選択します。

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

または、それを「最小のサプライズ」と呼ぶのではなく、2 つのサプライズのうち小さい方のサプライズと呼びましょう。

2 つの継承された関数から選択するようにコンパイラに要求している次のケースを考えてみましょう。オーバーロードの通常のルールが適用される場合、サブクラスで定義されたメソッドが選択されます。しかし、それは良い政策でしょうか?

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' answerで示されているように、矛盾しているようです。

于 2012-10-11T19:12:11.713 に答える