[英]In scala List :: doesn't do implicit conversion
在 scala 中,可以轉換Seq
的變量,但是如果我用::
構造Seq
則不起作用。 例如
case class A(s: String)
implicit def toA(s: String): A = A(s)
val Seq(a, b, c, d): Seq[A] = Seq("a", "b", "c", "d") // compiles
val Seq(e, f): Seq[A] = "e" :: "f" :: Nil // won't compile
Seq("a","b","c","d")
實際上是Seq.apply[X]("a","b","c","d")
,其中X
推斷為左手邊的A
並且在Seq.apply[A](...
中需要使用類型A
元素,因此字符串通過toA
隱式轉換為A
s(因此實際上是val Seq(a, b, c, d): Seq[A] = Seq.apply[A](A("a"), A("b"), A("c"), A("d"))
))。
但是"e" :: "f" :: Nil
實際上是::[Y]("e", ::[Z]("f", Nil))
,其中首先將Z
推斷為>: String
,然后將Y
推斷為推斷為>: String
因此其類型為>: List[String]
(實際上是List[Serializable]
),並且與類型模式Seq[A]
不匹配。 因此存在編譯錯誤。
基本上,事情是從String
到A
進行隱式轉換,而不是從Seq[String]
到Seq[A]
進行隱式轉換。
如果僅編寫val Seq(e,f) = "e" :: "f" :: Nil
則它將編譯,因為右側與左側的模式匹配。
同樣val Seq(f): Seq[A] = "f" :: Nil
編譯,因為在::[Z]("f", Nil)
中只有一個類型參數,並且可以推斷出它等於A
這里的問題是,編譯器沒有理由應用隱式轉換,直到為時已晚。 表達方式
"e" :: "f" :: Nil
創建與導致錯誤的Seq[A]
不兼容的List[String]
。
要解決此問題,您需要從List[String]
到List[A]
進行隱式轉換。
請注意,這也不起作用 :
"e" :: "f" :: List[A]()
您可以將String
添加到List[A]
這樣它就不會隱式轉換為A
,最終得到List[Serializable]
。
Error:(15, 31) type mismatch;
found : List[java.io.Serializable]
required: Seq[Main.A]
val Seq(e, f): Seq[A] = "e" :: "f" :: Nil
所以我想很明顯是一個類強制轉換異常
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.