在scala中List ::不进行隐式转换

问题描述 投票:0回答:3

在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
scala implicit-conversion
3个回答
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]不匹配。所以有编译错误。

基本上,你有一个从StringA的隐式转换,但不是从Seq[String]Seq[A]

如果你只写val Seq(e,f) = "e" :: "f" :: Nil然后这个编译,因为右侧匹配左侧的模式。

此外val Seq(f): Seq[A] = "f" :: Nil编译,因为在::[Z]("f", Nil)只有一个类型参数,它可以推断为等于A


0
投票

这里的问题是编译器没有理由应用隐式转换,直到为时已晚。表达方式

"e" :: "f" :: Nil 

创建一个与List[String]不兼容的Seq[A],这会导致错误。

要解决此问题,您需要从List[String]List[A]进行隐式转换。

请注意,这也不起作用:

"e" :: "f" :: List[A]()

你可以添加一个StringList[A]所以它不会隐式转换为A为你,你最终得到List[Serializable]


-3
投票
Error:(15, 31) type mismatch;
 found   : List[java.io.Serializable]
 required: Seq[Main.A]
  val Seq(e, f): Seq[A] = "e" :: "f" :: Nil

所以我猜这很明显是一个类强制转换异常

© www.soinside.com 2019 - 2024. All rights reserved.