向 val 添加显式类型可防止 val 在注释中用作常量
来自 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果没有类型,
final val
的作用就像一个文字常量——标识符在编译时被其值替换。有了类型,它就成为对存储在某处的某些内容的引用,不能在注释上使用。这是在规范第 4.1 节中定义的:
这是在 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:
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.