为什么这些函数擦除后类型相同?

asd*_*sds 2 java generics scala

def merge[X](list1: Option[List[X]], list2: Option[List[X]]): Option[List[X]]  
def merge[X](list1: Option[List[X]], elem: Option[X]): Option[List[X]]
Run Code Online (Sandbox Code Playgroud)

编译器说这两个函数在擦除后具有相同的类型

def merge[X](list1: Option[List[X]],list2: Option[List[X]]): Option[List[X]] at line 122 and
def merge[X](list1: Option[List[X]],elem: Option[X]): Option[List[X]] at line 131
have same type after erasure: (list1: Option, list2: Option)Option
Run Code Online (Sandbox Code Playgroud)

为什么擦除后Option[List[X]]Option[X]变得相同?我怎样才能让它们与众不同?

Gur*_*ron 5

\n

为什么擦除后Option[List[X]]Option[X]变得相同?

\n
\n

因为 的泛型类型参数Option[...]被删除(因此 和XList[X]被删除),因此两个方法将具有相同的签名。

\n
\n

我怎样才能让它们与众不同?

\n
\n

一种方法 - 将虚拟隐式参数添加到其中一种方法,以便它们具有不同的签名:

\n
def merge[X](list1: Option[List[X]], list2: Option[List[X]]): String = "1"\ndef merge[X](list1: Option[List[X]], elem: Option[X])(implicit d: DummyImplicit): String = "2"\n\nprintln(merge(Some(List(1)), Some(List(2)))) // 1\n\nprintln(merge(Some(List(1)), Some(2))) // 2\n
Run Code Online (Sandbox Code Playgroud)\n

对于 Scala 3(感谢@Ga\xc3\xabl J指出这一点)@targetName注释可以用来解决歧义:

\n
import scala.annotation.targetName\ndef merge[X](list1: Option[List[X]], list2: Option[List[X]]): String = "1"\n@targetName("merge_element")\ndef merge[X](list1: Option[List[X]], elem: Option[X]): String = "2"\n\nprintln(merge(Some(List(1)), Some(List(2)))) // 1\nprintln(merge(Some(List(1)), Some(2))) // 2\n
Run Code Online (Sandbox Code Playgroud)\n

  • 在 Scala 3 中,您可以使用“@targetName”来区分它们。 (2认同)