註解將元資訊與定義關聯在一起。例如,方法前的註解 @deprecated
會導致編譯器在使用該方法時印出警告。
object DeprecationDemo extends App {
@deprecated("deprecation message", "release # which deprecates method")
def hello = "hola"
hello
}
object DeprecationDemo extends App:
@deprecated("deprecation message", "release # which deprecates method")
def hello = "hola"
hello
這會編譯,但編譯器會印出警告:「有一個不建議使用的警告」。
註解子句套用於其後的第一個定義或宣告。一個定義和宣告前面可以有多個註解子句。這些子句的順序並不重要。
確保編碼正確性的註解
如果未滿足某個條件,某些註解實際上會導致編譯失敗。例如,註解 @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)
}
import scala.annotation.tailrec
def factorial(x: Int): Int =
@tailrec
def factorialHelper(x: Int, accumulator: Int): Int =
if x == 1 then 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)
}
import scala.annotation.tailrec
def factorial(x: Int): Int =
@tailrec
def factorialHelper(x: Int): Int =
if x == 1 then 1 else x * factorialHelper(x - 1)
factorialHelper(x)
我們將會收到訊息「遞迴呼叫不在尾端位置」。
影響程式碼產生的註解
某些註解(例如 @inline
)會影響產生的程式碼(也就是說,如果沒有使用註解,您的 jar 檔可能會有不同的位元組)。內嵌表示在呼叫位置插入方法主體中的程式碼。產生的位元組碼較長,但希望執行速度較快。使用註解 @inline
並無法確保方法將會內嵌,但如果且僅如果符合產生的程式碼大小的一些啟發法,它將會導致編譯器執行此動作。
某些註解(例如 @main
)會影響產生的程式碼(也就是說,如果沒有使用註解,您的 jar 檔可能會有不同的位元組)。方法上的 @main
註解會產生可執行程式,並將方法呼叫為進入點。
Java 註解
撰寫與 Java 互通的 Scala 程式碼時,註解語法有一些差異需要注意。注意:請務必將 -target:jvm-1.8
選項與 Java 註解搭配使用。
Java 以 註解的形式提供使用者定義的元資料。註解的一項主要功能是,它們仰賴指定名稱值對來初始化其元素。例如,如果我們需要一個註解來追蹤某些類別的來源,我們可能會將其定義為
@interface Source {
public String url();
public String mail();
}
然後套用如下所示
@Source(url = "https://coders.com/",
mail = "[email protected]")
public class MyJavaClass extends TheirClass ...
Scala 中的註解應用程式看起來像建構函式呼叫,要實例化 Java 註解,必須使用命名參數
@Source(url = "https://coders.com/",
mail = "[email protected]")
class MyScalaClass ...
如果註解只包含一個元素(沒有預設值),這種語法相當繁瑣,因此,根據慣例,如果名稱指定為 value
,則可以使用類似建構函式的語法在 Java 中套用
@interface SourceURL {
public String value();
public String mail() default "";
}
然後套用如下所示
@SourceURL("https://coders.com/")
public class MyJavaClass extends TheirClass ...
在這種情況下,Scala 提供了相同的可能性
@SourceURL("https://coders.com/")
class MyScalaClass ...
使用預設值指定 mail
元素,因此我們不需要明確提供它的值。但是,如果我們需要提供一個值,那麼在 Java 中我們也必須明確命名 value
參數
@SourceURL(value = "https://coders.com/",
mail = "[email protected]")
public class MyJavaClass extends TheirClass ...
Scala 在這方面提供了更大的靈活性,因此我們可以選擇僅命名 mail
參數
@SourceURL("https://coders.com/",
mail = "[email protected]")
class MyScalaClass ...