当类型被擦除时,隐式如何找到要用泛型调用的正确方法?

How is Implicit finding the correct method to be invoked with generics when types are erased?

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

如果 JVM 应该在 运行 时由于类型擦除而丢失泛型中的类型,在我下面的代码中,方法 fromListIntfromListString 看起来都像 List[任何]对吗? 因为当我用相同的名称命名两个函数时,我得到了错误 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

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

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

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

在 REPL 中,每次键入一行代码时,您都在编译它,然后再 运行 它。 test(List(0)) 被编译器转换为 test(fromListInt(List(0))) 之类的东西,这就是编译的内容,这就是您看到的行为。 test(List("0")) 被编译器转换为类似 test(fromListString(List("0"))) 的形式,这就是您在那里看到的行为。