在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
答案 0 :(得分:2)
Seq("a","b","c","d")
实际上是Seq.apply[X]("a","b","c","d")
,其中X
从左侧推断为A
。并且在Seq.apply[A](...
类型的A
元素中,因此字符串会通过A
隐式转换为toA
(因此实际上是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
。
答案 1 :(得分:0)
这里的问题是,编译器没有理由应用隐式转换,直到为时已晚。表达式
"e" :: "f" :: Nil
创建一个与引起错误的List[String]
不兼容的Seq[A]
。
要解决此问题,您需要从List[String]
到List[A]
进行隐式转换。
请注意,此无效:
"e" :: "f" :: List[A]()
您可以在String
上添加List[A]
,这样它就不会隐式转换为A
,最终得到List[Serializable]
。
答案 2 :(得分:-3)
Error:(15, 31) type mismatch;
found : List[java.io.Serializable]
required: Seq[Main.A]
val Seq(e, f): Seq[A] = "e" :: "f" :: Nil
所以我想这显然是类强制转换异常