在Scala 3中的不透明类型中擦除后相同的类型

发布于 2025-02-10 16:33:38 字数 1277 浏览 0 评论 0 原文

我想定义两个不透明类型的别名,它们通过相同的基础类型 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 注释确实解决了问题。

我的问题:为什么第一个代码片段编译而不是第二个代码段?肯定在第一个摘要中,两种方法在擦除后也具有相同的类型。

I want to define two opaque type aliases which are implemented with the same underlying type double.
I also want to define two extension methods on theses aliases which have the same name. The following compiles:

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

However I want these extension methods to be defined outside the scope of where the opaque type aliases are defined, i.e. in the MyMath object:

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 = ()

This gives the following compiler error:

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.

Adding a @targetName annotation does fix the issues.

My question: why does the first code snippet compile but the second one does not? Surely in the first snippet both methods also have the same type after erasure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兔姬 2025-02-17 16:33:38

编译后的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 type double).

Applying @targetName annotation lets you rename one or both methods in compiled class, removing the ambiguity.
See Relationship with Overriding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文