2011-07-28 8 views
9

で定数として使用されてからの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() 

誰かが説明できますか?

+0

なぜ「最終」というキーワードを使用していますか? – paradigmatic

+0

ダニエルが以下に言及するリテラル定数を作成するにはfinalが必要です。それがなければ、上記の同じエラーが発生します。 – scalapeno

答えて

8

タイプがない場合、final valはリテラル定数のように動作します。識別子はコンパイル時にその値に置き換えられます。この型では、どこかに格納されたものへの参照になり、注釈では使用できません。

これは仕様のセクション4.1で定義されている:

一定値の定義は、フォームEは定数式(§6.24)である

final val x = e 

です。最終的な修飾子は でなければならず、タイプ注釈は与えられません。 定数値xへの参照は、定数式として扱われます。 で生成されたコードは、定義の右側の のサイドeに置き換えられます。

これは、Scalaで本当の名前の定数を取得できる唯一の方法です。パフォーマンスのメリットがあります。実際には変異しないことが保証されています(タイプによってはfinal valでも反射で変更できます)。もちろん、アノテーションで使用することもできます。

+0

私はそれが起こっていたことを推測しましたが、なぜそれはそのように機能しますか?そうすることにいくつかの利点はありますか?これが有用な機能であるケースはありますか? – scalapeno

+0

@ tritium6私は自分の答えを広げましたが、アノテーションには有用な十分なケースはありませんか? –

+0

拡張いただきありがとうございます。あなたは正しい、注釈の場合は便利です。私が意味していたのは、型付き式の有用なケースがあるのです。なぜ、最終的なvalが参照である場合があるでしょうか? – scalapeno

関連する問題