Scala入门-注解(Annotations)
注解(Annotations)
注解将元信息与定义联系起来。例如,如果一个带有注解@deprecated
的方法被调用了,编译器就会打印一条警告。
object DeprecationDemo extends App {
@deprecated
def hello = "hola"
hello
}
这个程序可以编译,但是编译器将会打印一条警告:“there was one deprecation warning”。
一条注解语句将会应用到跟在它后面的第一个定义或者声明。在一个定义和声明之前可以有多个注解语句。这些语句之间的顺序没有任何影响。
确保编码正确的注解
如果没有满足特定条件,某些注解将会导致编译失败。例如,注解@tailrec
可以确保一个方法是尾部递归的。尾部递归可以保持内存开销恒定。下面展示了在计算阶乘的方法中是如何使用该注解的:
import scala.annotation.tailrec
def factorial(x: Int): Int = {
@tailrec
def factorialHelper(x: Int, accumulator: Int): Int = {
if (x == 1) accumulator else factorialHelper(x - 1, accumulator * x)
}
factorialHelper(x, 1)
}
方法factorialHelper具有@tailrec
,可以确保其确实是尾部递归的。如果就将factorialHelper的实现修改成下面这样,就会编译失败:
import scala.annotation.tailrec
def factorial(x: Int): Int = {
@tailrec
def factorialHelper(x: Int): Int = {
if (x == 1) 1 else x * factorialHelper(x - 1)
}
factorialHelper(x)
}
我们将会得到消息“Recursive call not in tail position”。
影响代码生成的注解
一些像@inline
这样的注解会影响代码生成(也就说生成的jar文件跟不用注解相比可能具有不同的字节)。内联的意思是将方法体内的代码插入到该方法被调用的位置。这样生成的结果字节码会变长,但是运行速度会变快。使用注解@inline
无法确保方法一定会变成内联的,但是当且仅当关于代码规模的一些试探被满足时,编译器就会将其编译为内联的。
Java注解
当写与Java交互的Scala代码时,关于注解语法有一些不同点需要注意。注:在使用Java注解时需要带上选项-target:jvm-1.8
。
Java具有以注解的形式表示的用户自定义元数据。注解的一个关键特征是它们通过指定name-value对来初始化它们的元素。例如,如果我们需要一个注解来跟踪一些类的来源,可以这样定义
@interface Source {
public String URL();
public String mail();
}
然后这样应用它
@Source(URL = "http://coders.com/",
mail = "support@coders.com")
public class MyClass extends HisClass ...
在Scala中使用一个注解看起来像一个构造函数调用,为了实例化一个Java注解,需要指定参数名:
@Source(URL = "http://coders.com/",
mail = "support@coders.com")
class MyScalaClass ...
如果注解只包含一个元素(没有默认值),这个语法是相当冗长的,所以习惯上,如果name被指定为value,则可以用类似构造函数的语法来在Java中使用它:
@interface SourceURL {
public String value();
public String mail() default "";
}
然后这样应用它
@SourceURL("http://coders.com/")
public class MyClass extends HisClass ...
在这个例子中,Scala提供了相同的能力
@SourceURL("http://coders.com/")
class MyScalaClass ...
元素mail被指定了一个默认值,所以我们不需要为它显式提供一个值。然而,如果需要给它提供值,在Java中我们不能混合搭配这两种形式:
@SourceURL(value = "http://coders.com/",
mail = "support@coders.com")
public class MyClass extends HisClass ...
在这方面Scala提供了更多的灵活性
@SourceURL("http://coders.com/",
mail = "support@coders.com")
class MyScalaClass ...
参考资料
本文译自Tour Of Scala – Annotations
上一篇:Scala入门-By-name参数(By-name parameters)
下一篇:Scala入门-默认参数值(Default Parameter Values)