2010-11-18 49 views
3

我想出一種方法在scala中的某個現有類中定義新方法。將方法注入到現有類中

例如,我認爲asInstanceOf[T]方法有太長的名字,我想as[T].

一個直接的方法來替代它可以是:

class WrappedAny(val a: Any) { 
    def as[T] = a.asInstanceOf[T] 
} 

implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a) 

有沒有一種更自然的方式與少代碼?

scala> class A 

defined class A 

scala> implicit def toA(x: Any): A = x 

toA: (x: Any)A 

scala> toA(1) 

和控制檯掛起:

此外,當我嘗試這一個奇怪的事情發生了。看起來toA(Any)不應該通過類型檢查階段,並且當它不是隱含的時候它不能通過。將所有代碼放入外部源代碼可能會產生相同的問題。這怎麼發生的?它是編譯器(版本2.8.0)的錯誤嗎?

回答

8

你的方法皮條Any沒有什麼技術上的錯誤,雖然我認爲這通常是不明智的。同樣,有一個原因asInstanceOfisInstanceOf是如此詳細地命名;這是爲了阻止你使用它們!幾乎可以肯定,一個更好的,靜態類型安全的方法可以做任何你想做的事情。

關於這會導致控制檯掛起爲例:toA聲明的類型爲Any => A,但你已經定義了它的結果作爲x,其類型爲Any,不A。這怎麼可能編譯?那麼請記住,當發生明顯的類型錯誤時,編譯器會查找任何可用的隱式轉換來解決問題。在這種情況下,它需要隱式轉換Any => A ...並找到一個:toA!所以原因toA類型檢查是因爲編譯器隱含重新定義爲:

implicit def toA(x: Any): A = toA(x) 

...這無限遞歸過程的結果,當您嘗試使用它。

+0

哇!這真太了不起了。你是怎麼想出這個想法的?而且,asInstanceOf [T]僅僅是一個例子。我只是好奇,是否有任何語法糖果在一般情況下工作。 – 2010-11-20 14:40:56

+0

作爲一般規則,如果代碼中存在明顯的類型錯誤,但編譯器接受它,則存在工作中的隱式轉換......以及它掛起的事實是主要線索:) – 2010-11-20 19:24:23

3

在第二個示例中,您將Any傳遞給必須返回A的函數。但是它永遠不會返回A,而是您通過的Any。然後,編譯器嘗試應用隱式轉換,而該轉換不會返回A,而是返回Any,依此類推。

如果定義爲TOA不是隱含的你:

scala> def toA(x: Any): A = x   
<console>:6: error: type mismatch; 
found : Any 
required: A 
     def toA(x: Any): A = x 
          ^
1

碰巧,這個已經在Scala的討論之前列出。 pimp我的類模式對於它的功能確實有點冗長,也許有可能在不引入新關鍵字的情況下清除語法。

關於新關鍵詞的一點是,Scala的目標之一是通過庫來擴展語言,而不是將語言變成一個巨大的被子,通過某人的標準來「足夠有用地添加到語言中」同時,讓其他想法變得不可能,因爲它們不被認爲是有用的和/或共同的。

無論如何,目前爲止還沒有出現,我也沒有聽說有任何工作正在朝着這個目標前進。歡迎您通過郵件列表加入社區,併爲其發展做出貢獻。

相關問題