1

在下面的代码中,我有一个函数test接收一个磁铁类型的对象,我有两个隐式方法将 List[Int] 转换为磁铁,另一个将 List[String] 转换为磁铁。

如果JVM由于运行时类型擦除而应该松散泛型中的类型,在我下面的代码中,方法fromListIntfromListString看起来都像 List[Any] 对吗?因为当我用相同的名称命名两个函数时,我收到错误error: double definition:提示 List[Int] 和 List[String] 被认为是相同的。

当我通过 List(0) 和 List("0") 时,在这种情况下如何找到正确的隐式方法?

scala> trait magnet {
     | def printSomething: Unit
     | }
defined trait magnet

scala> object magnet {
     | implicit def fromListInt(future: List[Int]): magnet = {
     | new magnet { def printSomething: Unit = println("test int") }
     | }
     | implicit def fromListString(future: List[String]): magnet = {
     | new magnet { def printSomething: Unit = println("test string") }
     | }
     | }
defined object magnet
scala> def test(in: magnet): Unit = {
     | in.printSomething
     | }
test: (in: magnet)Unit

scala> import magnet._
import magnet._

scala> test(List(0))
test int

scala> test(List("0"))
test string

4

2 回答 2

2

隐式在编译时解决,而不是在运行时解决。在编译时,没有任何内容被删除。编译器可以使用完整的类型信息。

在 REPL 中,每次键入一行代码时,都是在运行它之前对其进行编译。test(List(0))编译器将其转换为类似test(fromListInt(List(0))), 并且编译的内容,这就是您看到的行为。test(List("0"))被编译器转换为类似的东西test(fromListString(List("0"))),这就是你在那里看到的行为。

于 2019-05-12T10:47:29.570 回答
1

隐式在编译时解析。在编译时类型还没有被擦除。

test(List(0))其实是test(fromListInt(List(0)))test(List("0"))其实是test(fromListString(List("0")))

于 2019-05-12T10:47:04.697 回答