パラメータリストを渡すパラメータリストなしでメソッドを呼び出すことはmethod1()
できないため、宣言することはできません。def method =
scala> def method1 = 0
method1: Int
scala> method1()
<console>:9: error: Int does not take parameters
method1()
^
apply()
このエラーは、Scalaが の結果であるmethod1
を呼び出そうとしたことに注意してくださいInt
。
逆に、パラメーター リストを指定して vararg メソッドを呼び出すことはできません。
scala> def vararg(x: Int*) = x.size
vararg: (x: Int*)Int
scala> vararg
<console>:9: error: missing arguments for method vararg;
follow this method with `_' if you want to treat it as a partially applied function
vararg
^
したがって、最初のケースでは、示されている以外に考えられる動作はありません。
2 番目の例では、最初と最後のケースはあいまいではありません。(示されているように) パラメータ リストなしで vararg を呼び出すことはできず、パラメータを渡すパラメータなしでメソッドを呼び出すことはできません。パラメーターなしで空のパラメーター リストを使用してメソッドを呼び出すことができ.toString
ます。これは主に、Java API をより "きれいに" するために行われました。たとえば、 .
2 番目のケース (空のパラメーター リストを指定してメソッドを呼び出す) では、あいまいさが生じます。次に Scala は、一方が他方より具体的かどうかを判断しようとします。
ここで少し寄り道をしてみましょう。より具体的な方法を確認する理由 これがあるとします:
object T {
def f(x: AnyRef) = x.hashCode
def f(x: String) = x.length
}
この種のことは、Java API では比較的一般的です。誰かがf("abc")
を呼び出した場合、当然、コンパイラは最初のメソッドではなく 2 番目のメソッドを呼び出すと予想されますが、どちらも有効です。では、それらを明確にする方法は?おそらく、String
渡されたものと完全に一致するので、それを使用するかもしれませんよね? では、次のことを考えてみてください。
object T {
def f(x: AnyRef) = x.hashCode
def f(x: java.util.Collection[_]) = x.size
}
そして、私はそれを次のように呼びf(new ArrayList[String])
ます。AnyRef
はクラスですが、Collection
はインターフェースなので、クラスよりもインターフェースを優先するのでしょうか? そして、期待する別のメソッドがあった場合はどうなるでしょうかList
-それもインターフェースです。
したがって、このあいまいさを解決するために、Scala は最も具体的な概念を使用します。これは、実際には非常に簡単に適用できる概念です。
まず、Scala は一方が他方と同じくらい具体的であるかを検証します。型と式に関して定義された 4 つの単純なルールがありますが、その要点は、a のパラメーターで b を呼び出すことができる場合、メソッド a はメソッド b と同じくらい具体的であるということです。
この場合、method2()
は と同じくらい具体的です。これは、空のパラメーター リストで呼び出すことができるmethod2(args: Any*)
ためです。method2(args: Any*)
一方、method2(args: Any*)
は ほど具体的ではありませんmethod2()
。なぜなら、method2()
は 型の引数で呼び出すことができないからAny
です。
次に、Scala は、メソッドの 1 つを定義するクラスの 1 つが、他のメソッドを定義するクラスのサブクラスであるかどうかを検証します。この規則は、この場合には適用されません。
最後に、Scala は、適合する上記の 2 つの基準のそれぞれについて、各メソッドに 1 を追加します。So method2()
has weight 1, and method2(args: Any*)
has weight 0. 一方の重みが他方よりも大きい場合、そのメソッドが最も具体的であると見なされます。
これまで見てきたように、method2()
が最も具体的なものであるため、それが選択されます。