在Scala注解中使用常量的最佳实践

18

我选择 Tapestry 5 作为我的 Web 框架。Tapestry 允许我在配置类中定义符号,并将符号注入到其他组件中。

例如,

public interface SymbolConstants {
  static String DEFAULT_TIMEOUT_KEY = "default.timeout"; 
}

public class AppModule {
   void contributeApplicationDefault(Configuration conf) {
       conf.add(SymbolConstants.DEFAULT_TIMEOUT_KEY, "10");
   }
}

public class MyComponent {
  @Symbol(SymbolConstants.DEFAULT_VALUE_KEY)
  private long timeout;
}

定义静态常量并将它们用作注解值的能力使我可以进行编译时检查。

我想知道如何定义常量并将它们用作 Scala 注解的值。如果不行,那么在 Scala 中定义/限制我们可以分配给注解的值的最佳方法是什么。

2个回答

23

需要使用 'final' 关键字来使编译器像在 Java 中一样发出它。例如:

object Foo
{
   final val MY_SYMBOLIC_CONSTANT="whatever"
}

看起来,否则你只会在后台获取一个无法静态计算的访问器方法。


在Scala 2.10.3中对我有效! - Erik Kaplun
10
在Scala 2.10.x和Scala 2.11.x版本中,这个代码可以正常工作 - 只要确保您不添加类型注释。如果您添加了类型注释,似乎Scala编译器会将您的常量编译为方法而不是静态最终变量。 - Cubic
请参考@extempore在此处的答案,了解更多背景/示例:https://dev59.com/32Ij5IYBdhLWcg3wv3e2 - bbarker
在我的Scala 2.12.3中运行良好。 - Zhuo YING
适用于2.12.2版本。 - Robert Gabriel

1

在Scala 2.8.1.final、2.8.2.final或2.9.1.final版本中似乎不可能实现(所有版本都得到相同的结果):

object Constant { val UNCHECKED = "unchecked" }

class Test {                                       
    @SuppressWarnings(Array(Constant.UNCHECKED))   
    def test: Unit = println("testing.. 1, 2... 3")
}

.

<console>:7: error: annotation argument needs to be a constant; found: Constant.UNCHECKED
           @SuppressWarnings(Array(Constant.UNCHECKED))

它不起作用是因为 SuppressWarnings 需要一个数组。如果你使用其他注释,它就可以工作了。试试 @SerialVersionUID。http://www.scala-lang.org/node/106 - onof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接