2016-08-14 31 views
2

我寫這個例子理解隱含<<參數

class TestMatch[T](private val t: T){ 
    def test()(implicit ev: T <:< Option[Int]) = println(ev(t).get) 
} 

和測試它

val tm = TestMatch(Some(10)) 
tm.test() //fine 

val tm2 = TestMatch(10) 
tm2.test() //compilation error 

的問題是誰創造了implicit ev: T <:< Option[Int]當調用test方法?我知道我沒有。也許編譯器知道implicit <:<並知道如何處理它。

<:< Documenation不太清楚

要限制任何抽象類型T這是在範圍上的方法的 參數列表(不僅僅是方法本身的類型參數)只需添加 的隱含參數T <:< U類型,其中U是所需 的上限;或下限,請使用:L <:< T,其中L是 所需的下限。

這是否意味着,編譯器將採取其他的本身?我只是加了implicit ev: T1 <:< T2

+0

基於您已發佈的最近問題,你似乎有你的斯卡拉知識一些明顯的差距。我建議你閱讀一本關於Scala語言和Scala編程的好書。 –

回答

2

第一個代碼段因爲Predef.identity而編譯,這意味着您始終可以將T類型隱式轉換爲T(本例中爲Option[Int])類型。否則,你需要自己把一個暗示帶入scopre。

1

這是否意味着,編譯器將採取其他的本身?

編譯器將搜索一個隱含的範圍。如果它找到匹配項,它將提供它,如果它不能,你會得到一個編譯錯誤。有了您的例子中,編譯器發現Some[Int]堅持以Some[Int] <:< Option[Int]隱含的要求,因爲它是Option[Int]直接亞型。

scalac編譯代碼時,你可以看到這一點:

val tm: TestMatch[Some[Int]] = new TestMatch[Some[Int]](scala.Some.apply[Int](10)); 
tm.test()(scala.this.Predef.$conforms[Some[Int]]); 

哪裏是爲Int(你的第二個例子),存在範圍相匹配的要求沒有隱式的,Int不是Option[Int]一個亞型。

+1

任何想法爲什麼添加這種東西不起作用? '隱式def nonZeroInt(i:Int):Option [Int] = if(i == 0)沒有其他Some(i)'(我與'test'調用相同的級別) – Dici

1

編譯器將嘗試尋找各種預定位置中隱含參數。如果它找不到它會引發錯誤。此鏈接可以幫助:http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

enter image description here

+0

這幾乎是一個鏈接 - 只回答 – Dici

+0

好吧,我可以刪除它,如果你想。我認爲通過這個圖像可以更容易地看到編譯器尋找隱含的所有位置,而不必鍵入它們。 – Samar

+0

我認爲這個鏈接很有用,但是你應該嘗試給它增加一些價值。不要刪除你的答案只爲我:頁 – Dici