2015-07-12 26 views
3

打擾了很長的設置。這個問題涉及到,但沒有回答,Scala: ambiguous reference to overloaded definition - best disambiguation?斯卡拉含糊不清的函數調用

我是很新,Scala和個東西是扔我了是斯卡拉兩個:

  • 擁有一流的功能,使用對象,點符號,沒有任何括號中的參數時,
  • 通話功能列表(好像該功能是屬性)

這兩種語言功能令我感到困惑。看看下面的代碼:

 
class MyClass { 
    def something(in: String): String = { 
     in + "_X" 
    } 

    def something: String => String = { 
     case _ => "Fixed" 
    } 
} 

val my = new MyClass() 

println(List("foo", "bar").map(my.something)) 

我希望通過調用相匹配的map的需要String => ?論點something原型打印List("foo_X", "bar_X")。相反,輸出是List("Fixed", "Fixed") - Scala 2.11正在調用無參數something(),然後將其返回值傳遞給map

如果我們註釋掉something的第二個無參數原型,則輸出將變爲預期結果,表明其他原型在上下文中有效。

向第二個原型添加一個空參數列表(使其爲def something())也會改變行爲。

改變my.somethingmy.something(_)醒來斯卡拉高達然後才默默地忽略了不確定性:

 
error: ambiguous reference to overloaded definition, 
both method something in class MyClass of type => String => String 
and method something in class MyClass of type (in: String)String 
match argument types (String) 
println(List("foo", "bar").map(my.something(_))) 

即使使用所謂換這個目的的魔法尾隨下劃線不起作用:

 
val myFun: (String) => String = my.something _ 

這導致:

 
error: type mismatch; 
found :() => String => String 
required: String => String 
val myFun: (String) => String = my.something _ 

個我的問題:

  • 如果我有MyClass正是因爲寫(不更改原型,尤其是不要添加一個空的參數列表的原型之一),我怎麼告訴斯卡拉,明確,我想要的something的第一個單參數版本作爲參數傳遞給另一個調用?
  • 由於顯然有兩個令人滿意的參數可以傳遞給map,爲什麼Scala編譯器不會將歧義報告爲錯誤?
  • 有沒有辦法可以禁用Scala的行爲(有時並非總是)將foo.bar等同於foo.bar()
+1

這是在「風格一點點」一章中的Atomic Sc​​ala中討論的。如果一個方法沒有參數,可以用括號定義或不定義。如果用圓括號定義,可以用或不用它們來調用。但是,如果沒有括號定義,只能在沒有括號的情況下調用它。風格約定是用括號定義方法,如果調用方法改變了對象的內部狀態,或者在沒有括號的情況下定義它們。在你設計的例子中,編譯器似乎盡力根據包括括號在內的簽名選擇正確的函數。 – 2015-07-12 20:26:46

回答

0

我已經在Scala問題跟蹤器上提交了一個錯誤,並且共識似乎是這個行爲是一個錯誤。編譯器應該對關於「my.something」的模糊引用發出錯誤。