为什么将成员变量声明为元组时会出现擦除警告?

发布于 2024-10-20 20:37:14 字数 551 浏览 1 评论 0原文

看一下这个 Scala 类:

class Example {
  val (x, y): (Int, Int) = (1, 2)
}

编译此结果会产生警告:

Example.scala:2: warning: non variable type-argument Int in type pattern
               (Int, Int) is unchecked since it is eliminated by erasure
    val (x, y): (Int, Int) = (1, 2)
                ^

删除显式类型注释可以消除此警告:

class Example {
  val (x, y) = (1, 2)
}

为什么我会收到警告以及为什么删除显式类型注释可以消除它?据我所知,没有任何真正的变化,xy 仍然是 Int 类型,没有类型注释。

Have a look at this Scala class:

class Example {
  val (x, y): (Int, Int) = (1, 2)
}

Compiling this results in a warning:

Example.scala:2: warning: non variable type-argument Int in type pattern
               (Int, Int) is unchecked since it is eliminated by erasure
    val (x, y): (Int, Int) = (1, 2)
                ^

Removing the explicit type annotation gets rid of this warning:

class Example {
  val (x, y) = (1, 2)
}

Why do I get the warning and why does removing the explicit type annotation get rid of it? As far as I can see nothing really changes, x and y are still of type Int without the type annotation.

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

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

发布评论

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

评论(2

小ぇ时光︴ 2024-10-27 20:37:14

您可以将示例重写为:

class Example {
  val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}

此模式匹配实际上由 2 个匹配组成 - 它现在表示:采用 Tuple2[Int, Int] 类型的右侧对象并调用方法 unapply[ Tuple2 伴随对象上的 Int, Int]。然后,unapply[Int, Int] 将验证该对象是否确实具有 Tuple2 类型,并且其结果值将用于将值绑定到变量 x< /code> 和 y

之后,此模式匹配包含 : Tuple2[Int, Int],因此它尝试动态执行 isInstanceOf[Tuple2[Int, Int]] 检查以查看是否对象还具有 Tuple2[Int, Int] 类型。但是,泛型类型信息在运行时会被删除,因此编译器会警告它实际上无法生成验证该对象是否已为类型参数 [Int, Int] 实例化的代码。

同样的,在下面的模式匹配中:

val a: AnyRef = (1, 2)
a match {
  case t2: Tuple[Int, Int] => 
}

你会得到类似的警告。

You could rewrite your example to:

class Example {
  val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}

This pattern match actually consists of 2 matches - it now says: take the right hand side object of type Tuple2[Int, Int] and call the method unapply[Int, Int] on the Tuple2 companion object. The unapply[Int, Int] will then verify that the object really has the type Tuple2, and its result value will be used to bind values to variables x and y.

After that, this pattern match contains : Tuple2[Int, Int], so it tries to do an isInstanceOf[Tuple2[Int, Int]] check dynamically to see if the object additionally has the type Tuple2[Int, Int]. However, generic type information is erased at runtime, so the compiler warns that it cannot actually produce code which verifies that the object is instantiated for type parameters [Int, Int].

In the same way, in the following pattern match:

val a: AnyRef = (1, 2)
a match {
  case t2: Tuple[Int, Int] => 
}

you would get a similar warning.

‘画卷フ 2024-10-27 20:37:14

我认为你的问题的简短答案是:

class Example {
  val (x: Int, y: Int) = (1, 2)
}

因为 (Int, Int)不是类型,而 (x: Int, y: Int) code> 是有效的模式表达式。

I think the short answer to your question is:

class Example {
  val (x: Int, y: Int) = (1, 2)
}

because (Int, Int) is not a type, while (x: Int, y: Int) is a valid pattern expression.

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