2013-03-04 77 views
4

我聲明瞭兩個實用方法爲implicit「參數化重載隱式方法不可視爲視圖邊界」編譯器警告的意思是什麼?

class MyClass { ... } 
object MyClass { 
    implicit def finish: MyClass[Any,Nothing,Unit] = finish(()); 
    implicit def finish[R](result: R): MyClass[Any,Nothing,R] = ... 
} 

和我得到的編譯器警告:

參數重載隱式方法是不可見的視圖邊界

這是什麼警告意思?

+0

請發佈代碼nsippet,**不會**重現該問題,並指定您的Scala版本。 – 2013-03-04 08:45:16

+0

沒關係,你的代碼片段確實會產生警告,但只在** scala 2.9.x **(不再在Scala 2.10中)。 – 2013-03-04 08:52:48

回答

4

這裏的「參數」確實應該「類型參數」。 或者在其他wods,警告說,因爲你已經定義的隱式轉換,既重載(有相同名稱的其他方法),並通用,則該方法不能實際用作隱觀,儘管它可以用來隱式地轉換一個單純的值。 我將設法示出了具有一個示例的區別:

class MyClass 
object MyClass { 
    implicit def finish: MyClass = null 
    implicit def finish[R](result: R): MyClass = null 
} 

val a: Int = 123 
val b: MyClass = a // Compiles fine: implicit conversion properly applied 

def foo[R<%MyClass](r: R) {} 
foo(123) // Error: No implicit view available from Int => Test.MyClass 

在上面的代碼段中,a(的Int類型)隱式轉換爲MyClass,因此隱式轉換按預期方式工作。

然而,最有趣的部分是與foo方法。它被視爲與MyClass綁定。換句話說,您應該能夠傳遞foo任何可隱含轉換爲MyClass的值。但是這裏沒有編譯。這是編譯器警告你的這個錯誤。 果然,如果你註釋掉finish的第一超載(當一個不帶一個類型參數),或使他們不超載重命名版本(比如你重命名爲finish2其中之一),那麼編譯錯誤消失。

如果您想知道第一種情況(直接隱式轉換)和第二種情況(調用具有視圖邊界的方法)之間的區別是什麼,它們允許編譯好而不是另一種,關鍵是一個視圖邊界需要傳遞一個隱式函數值。

事實上,

def foo[R<%MyClass](r: R) 

相同

def foo[R](r: R)(implicit conv: R => MyClass) 

所以調用foo時,編譯器不僅需要找到合適的隱式轉換,同時也促進了隱式轉換方法(第二個finish重載)到一個函數實例,並將其隱式傳遞給foo

我認爲,這是本次促銷活動,編譯器(出於某種原因)不知道如何在類型參數和重載方法的情況下做的。 這純粹是猜測,但我敢肯定,這只是一個實現的限制:這將非常是可行的,但它會介紹,這是不認爲足夠重要,足以執行問題(畢竟,你可以通過只重命名修復隱式轉換方法)。

作爲邊注,警告未在階2發射(默認)。10(它被認爲太吵了,在scala中使用了類的類型),但真正的問題仍然存在,並且foo的調用仍然無法編譯。

相關問題