我有以下代碼。
object example {
def foo(a: Any) = "Object"
def foo(a: String, args: String*) = "String"
def main() = {
println(foo("ABC")) // Should print "String"
}
}
在 Scala 2 中,此代碼運行良好。當我foo使用單個字串引數呼叫時,兩個多載都是有效的,但String一個更具體,所以它被呼叫。在 Scala 3 中,這是模棱兩可的。
-- [E051] Reference Error: overloads.scala:9:12 --------------------------------------------------------------------
9 | println(foo("ABC"))
| ^^^
| Ambiguous overload. The overloaded alternatives of method foo in object example with types
| (a: String, args: String*): String
| (a: Any): String
| both match arguments (("ABC" : String))
等效代碼(兩個多載,其中一個更具體并具有可變引數)也適用于 Java。Scala 3 中究竟發生了什么變化,使這個特定的呼叫變得模棱兩可?這種行為是有意的嗎?在這種情況下,我如何告訴 Scala 呼叫哪個多載?
對于它的價值,我很清楚在 Scala 中強烈不鼓勵方法多載。在我的實際代碼中,我正在與具有多載.append方法的 Java 構建器類互動,因此我無法控制函式簽名。
uj5u.com熱心網友回復:
此PR中提到了此行為,特別是在此評論中。我不知道這是否會“修復”或者是否完全符合預期。
請注意,以下內容并非模棱兩可:
def foo(s: String)
def foo(a: String, other: String*)
foo("fine!")
使用def foo(s: Any),您可以像這樣顯式選擇一個多載或另一個多載:
foo("fine": Any) // calls foo(Any)
foo("fine", Nil: _*) // calls foo(String, String*) with an empty vararg
PS:我不會說“強烈不鼓勵”多載,但我們必須小心并承認某些情況對于編譯器和人類來說是模棱兩可的。對我來說,foo("")應該參考哪個定義并不明顯,所以在這種情況下更明確并不是完全瘋狂的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/486225.html
