在 scala List :: 中不进行隐式转换
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
(所以它实际上是 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
创建了一个 List[String]
,它与导致错误的 Seq[A]
不兼容。
要解决此问题,您需要进行从 List[String]
到 List[A]
的隐式转换。
请注意,此 也不起作用 :
"e" :: "f" :: List[A]()
您可以将 String
添加到 List[A]
,这样它就不会隐式转换为 A
,您最终会得到 List[Serializable]
。
在 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
(所以它实际上是 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
创建了一个 List[String]
,它与导致错误的 Seq[A]
不兼容。
要解决此问题,您需要进行从 List[String]
到 List[A]
的隐式转换。
请注意,此 也不起作用 :
"e" :: "f" :: List[A]()
您可以将 String
添加到 List[A]
,这样它就不会隐式转换为 A
,您最终会得到 List[Serializable]
。