2012-07-15 108 views
7

現在我看到有一個相關的問題問的這些運營商(<:<,<%<,=:=)在這裏做的:<:<,<%<,=:=的Scala實現究竟如何在編譯器中工作?

What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?

但我仍然感到困惑的具體實現。特別是,我假設一旦你放置了一個隱含的參數來斷言一個特定的關係,那麼你可以使用變量,就好像它們已經被自動正確地轉換一樣。這將編譯:

class Foo[T](a: T) { 
    def splitit(implicit ev: T <:< String) = a split " " 
} 

但是,如何在編譯器中實際工作?是否有一些神奇的編譯器支持這些運算符,如果沒有,那麼允許它從定義中推斷這種關係的底層機制是什麼? (這個機制是專門爲了讓這些操作符工作而添加的,它們對這些特定的操作符有多特殊?)似乎有點神奇,你可以放置一個額外的隱式參數,它以某種方式改變了編譯器對類型的解釋。

+2

他們的來源https://github.com/scala/scala/blob/v2.9.2/src/library/scala/Predef.scala#L394 – pedrofurla 2012-07-15 04:12:17

回答

8

該實現有點棘手,但沒有什麼神奇。

有一個在Predef一個隱含的方法當你嘗試調用你的方法可以用於任何A

implicit def conforms[A]: A <:< A 

提供A <:< A類型的值,它會尋找T <:< String類型的隱含價值。編譯器將檢查conforms[T]是否爲有效值。假設TNothing,那麼將會有一個隱含的值Nothing <:< Nothing,它將允許您的方法調用進行編譯。由於道路<:<定義

sealed abstract class <:<[-From, +To] 

From容許變化並To容許變化了。因此Nothing <:< Nothing仍然是有效的Nothing <:< String,因爲NothingString的子類型。 A String <:< String也是有效的Nothing <:< String,因爲String是超類型Nothing(但編譯器似乎總是選擇第一種類型)。

你可以調用它的String方法,因爲<:<也延伸=>又名Function1並作爲從TString的隱式轉換,基本上結束了做一個安全的演員。

=:=是相同的東西,除了它沒有任何差異註釋定義,所以類型必須完全匹配。

<%<被定義像<:<但隱式方法是有點不同的,它增加了另一參數來指定綁定

implicit def conformsOrViewsAs[A <% B, B]: A <%< B 

它還棄用的圖。

+0

謝謝!以下是解釋編譯器如何讓你調用字符串方法(或其他)的關鍵: _你可以調用字符串方法,因爲<:<也擴展=>又名Function1,用作從T到字符串的隱式轉換,基本上結束了做一個安全cast._ – 2012-07-22 00:17:33

相關問題