开发者

Adding explicit type to val prevents val from being used as a constant in annotation

开发者 https://www.devze.com 2023-03-24 03:25 出处:网络
From the REPL: scala> final val x = \"x\" x: java.lang.String(\"x\") = x scala> @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 cl开发者_JAVA百科ass foo()

Can someone explain why this only works without a type?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消