2013-12-17 45 views
1

結合在下面的代碼scalas能力所及的範圍,最後一行不起作用:什麼是上隱式的轉換

case class B(v:String) 
case class C(s:B,r:B) 

object TestImplicits { 
    implicit def str2b(s:String) : B = B(s) 
    implicit def in2b(i:(B,B)) :C = C(i._1,i._2) 

    val t : B = "hello" 
    val tb : (B,B) = ("hello","there") 
    val c : C = tb 
    val cb : C = (B("hello"),B("there")) 
    val n : C = ("hello","there") 
} 

我不明白爲什麼不 - 它知道如何轉換(B, B) - > C和String-> B,它可以轉(String,String) - >(B,B)。所有的部分都在那裏,但是如果沒有明確的(String,String) - > C方法,它就無法工作。

有什麼解決方法嗎?

+0

羅賓 - 它完全是,和回答正是我所需要的(即使它看起來很漂亮......)。我應該完全刪除這個問題,還是留下一個指向現有答案的指針?我認爲這個問題更簡潔,但另一個問題的答案是真實的。 –

回答

0

編譯器只會搜索直接轉換,它不知道如何編寫2個隱式轉換以達到所需的類型。解決方法是編寫從字符串元組到C的第三個隱式轉換,或將中間Bs存儲在值中。

1

基於其他linked question,這是可以做到這樣的:

object TestImplicits { 
    implicit def str2b(s:String) : B = B(s) 
    implicit def in2b[B1 <% B](i:(B1,B1)) :C = C(i._1,i._2) 

    val t : B = "hello" 
    val tb : (B,B) = ("hello","there") 
    val c : C = tb 
    val cb : C = (B("hello"),B("there")) 
    val n : C = ("hello","there") 
} 

注意,對於IN2B簽名現在已經改變 - 這相當於implicit def in2b(i:(B,B))(implicit ev: B1=>B)