在Scala 3中的不透明类型中擦除后相同的类型
我想定义两个不透明类型的别名,它们通过相同的基础类型 double
实现。
我还想在具有相同名称的这些别名上定义两种扩展方法。以下编译:
object MyMath1:
object Logarithms1:
opaque type Logarithm1 = Double
extension (l1: Logarithm1) def foo: Unit = ()
object Logarithms2:
opaque type Logarithm2 = Double
extension (l2: Logarithm2) def foo: Unit = ()
import Logarithms1.Logarithm1
import Logarithms2.Logarithm2
但是,我希望这些扩展方法在定义不透明类型别名的范围之外定义,即在 mymath
对象中:
object MyMath2:
object Logarithms1:
opaque type Logarithm1 = Double
object Logarithms2:
opaque type Logarithm2 = Double
import Logarithms1.Logarithm1
import Logarithms2.Logarithm2
extension (l1: Logarithm1) def foo: Unit = ()
extension (l2: Logarithm2) def foo: Unit = ()
这给出以下编译器错误:
Double definition:
def foo(l1: MyMath.Logarithms1.Logarithm1): Unit in object MyMath at line 52 and
def foo(l2: MyMath.Logarithms2.Logarithm2): Unit in object MyMath at line 53
have the same type after erasure.
Consider adding a @targetName annotation to one of the conflicting definitions
for disambiguation.
添加>
> @targetName
注释确实解决了问题。
我的问题:为什么第一个代码片段编译而不是第二个代码段?肯定在第一个摘要中,两种方法在擦除后也具有相同的类型。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编译后的Java类不得具有两种方法,其签名(类型擦除后的名称 +参数类型)一致。
在您的第一个片段中,方法在不同的对象中声明,因此被编译为不同类别的方法,因此没有冲突。
在第二种情况下,两种方法都应作为同一类的方法渲染。由于不透明类型被编译类中的基础类型所取代,因此存在冲突(同名
foo
,相同的删除参数类型double
)。应用
@targetName
注释使您可以在编译类中重命名一种或两种方法,从而删除歧义。参见。
A compiled Java class must not have two methods whose signatures (name + argument types after type erasure) coincide.
In your first snippet the methods are declared in different objects and are therefore compiled to methods of different classes, so there is no conflict.
In the second case both methods are to be rendered as methods of the same class. Since opaque types are replaced by the underlying type in the compiled class, there is a conflict (same name
foo
, same erased argument typedouble
).Applying
@targetName
annotation lets you rename one or both methods in compiled class, removing the ambiguity.See Relationship with Overriding.