向 val 添加显式类型可防止 val 在注释中用作常量

发布于 2024-11-26 17:56:09 字数 485 浏览 2 评论 0原文

来自 REPL:

scala> final val x = "x"
x: java.lang.String("x") = x

scala> @javax.persistence.Table(name = x) case class foo()
defined class foo

scala> final val x:java.lang.String = "x"
x: java.lang.String = x

scala> @javax.persistence.Table(name = x) case class foo()
<console>:6: error: annotation argument needs to be a constant; found: x
       @javax.persistence.Table(name = x) case class foo()

有人可以解释为什么这只能在没有类型的情况下起作用吗?

From the REPL:

scala> final val x = "x"
x: java.lang.String("x") = x

scala> @javax.persistence.Table(name = x) case class foo()
defined class foo

scala> final val x:java.lang.String = "x"
x: java.lang.String = x

scala> @javax.persistence.Table(name = x) case class foo()
<console>:6: error: annotation argument needs to be a constant; found: x
       @javax.persistence.Table(name = x) case class foo()

Can someone explain why this only works without a type?

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

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

发布评论

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

评论(1

把回忆走一遍 2024-12-03 17:56:09

如果没有类型,final val 的作用就像一个文字常量——标识符在编译时被其值替换。有了类型,它就成为对存储在某处的某些内容的引用,不能在注释上使用。

这是在规范第 4.1 节中定义的:

常量值定义的形式为

最终值 x = e

其中 e 是常量表达式(第 6.24 节)。最终修饰符必须是
存在并且不能给出类型注释。参考文献
常量值 x 本身被视为常量表达式;在
生成的代码将被定义的右侧替换
e 面。

这是在 Scala 中获得真正的命名常量的唯一方法。它们具有性能优势,确实保证不会发生变化(甚至可以通过反射更改类型的final val),当然,它们可以在注释中使用。

Without the type, final val acts like a literal constant -- the identifier is replaced by its value at compile time. With the type, it becomes a reference to something stored somewhere, which cannot be used on annotations.

This is defined on section 4.1 of the specification:

A constant value definition is of the form

final val x = e

where e is a constant expression (§6.24). The final modifier must be
present and no type annotation may be given. References to the
constant value x are themselves treated as constant expressions; in
the generated code they are replaced by the definition's right-hand
side e.

This is the only way you can get true named constants in Scala. They have performance benefits, they are really guaranteed not to mutate (even a final val with a type can be changed through reflection) and, of course, they can be used in annotations.

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