深入瞭解 Rust 的聲明性標記
在 Rust 中,聲明性標記是指放置在函數定義、模塊、類型等上面的屬性。它們提供額外的信息或改變代碼的行爲。Rust 中的聲明性標記以井號 (#) 開頭,放在方括號 ([]) 內。例如,一個聲明性標記可以表示成這樣:#[attribute]。
聲明性標記主要分爲三大類:條件編譯、crate-level 屬性以及函數和模塊級屬性。
條件編譯
條件編譯是通過屬性控制的,允許有條件地編譯部分代碼。Rust 通過兩個關鍵屬性來支持這一點:
1,cfg:此屬性包含基於傳遞給編譯器的標記代碼。它可以在定義類型的地方使用,函數、實現塊、結構體等。
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
println!("You're running linux!");
}
2,cfg_attr:此屬性允許基於條件標記實現配置。
#[cfg_attr(feature = "debug-mode", derive(Debug))]
struct Test {
value: i32,
}
在上面的代碼中,只有在啓用 Debug 模式時,纔會爲結構體 Test 派生 Debug 特徵。
Crate-level 屬性
Crate 級別的屬性適用於整個 crate,它們通常放在主文件 (lib.rs 或 main.rs) 的頂部。一些常用的 crate 級別的屬性是:
1,crate_name:該屬性允許手動設置 crate 的名稱。
#![crate_name = "my_crate"]
2,crate_type:該屬性允許定義 crate 的類型 (庫、二進制文件等)。
#![crate_type = "lib"]
3,deny,warn,allow,forbid:這些屬性用於在 crate 級別處理警告或 lint 檢查。
#![deny(missing_docs)]
4,macro_use:這個屬性允許從外部 crate 中使用宏。
#[macro_use]
extern crate log;
函數和模塊級屬性
這些屬性適用於函數、模塊、結構、枚舉、特徵等。下面是一些常見的:
1,test:該屬性將函數標記爲單元測試。
#[test]
fn test_addition() {
assert_eq!(2 + 2, 4);
}
2,derive:這個屬性自動爲用戶定義的類型創建特徵的實現。
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
3,inline:該屬性向編譯器建議,它應該將函數代碼的副本內聯到其調用者,從而可能提高運行時性能。
#[inline]
fn add(x: i32, y: i32) -> i32 {
x + y
}
- deprecated:此屬性可以表示不應該使用的代碼項,並將在將來的版本中刪除。
#[deprecated(since = "1.1.0", note = "請使用' new_function '代替")]
fn old_function() {
//
}
屬性中的派生宏
特別要提一下派生屬性,它允許 Rust 自動爲結構體或枚舉生成某些特徵。默認情況下,Rust 可以派生 10 種不同的特性:
-
Clone
-
Copy
-
Debug
-
Default
-
Eq
-
PartialEq
-
Ord
-
PartialOrd
-
Hash
-
Drop
#[derive(Debug, PartialEq, Eq)]
struct Point {
x: i32,
y: i32,
}
在本例中,Point 結構體自動實現 Debug、PartialEq 和 Eq 特徵。
過程宏中的屬性宏
Rust 還支持過程宏,包括屬性宏。雖然在技術上不是屬性,但它們的行爲類似,可用於調整函數、結構體的行爲。
屬性宏的定義如下:
#[macro_name(attributes)]
這方面的一個例子是流行的 serde 庫的派生宏:
#[derive(Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
在這個例子中,Serialize 和 Deserialize 是過程宏中的屬性宏,它們生成將 Point 實例轉換爲各種數據格式所需的代碼。
文檔屬性
文檔是任何代碼庫的一個基本方面,Rust 通過屬性提供了對文檔的內置支持:
doc:這個屬性允許在代碼中爲模塊、函數、結構體、枚舉、特徵、類型等編寫文檔註釋。
/// 這是下面結構體的文檔註釋。
#[doc = "表示二維空間中的一個點。"]
struct Point {
x: i32,
y: i32,
}
在這個例子中,doc 屬性用於爲 Point 結構體生成文檔。
死代碼和未使用檢測
Rust 的屬性系統還可以幫助防止常見的編碼錯誤:
dead_code:此屬性可用於對從未調用的代碼消除警告。
#[allow(dead_code)]
fn unused_function() {
//
}
must_use:當函數的結果未被使用時,函數的這個屬性將產生一個警告。
#[must_use]
fn function_with_important_result() -> i32 {
//
return 42;
}
總結
聲明性標記在塑造代碼的行爲和屬性方面起着至關重要的作用。它們提供了元編程功能,允許開發人員用額外的信息或行爲註釋他們的程序。這種能力對於編程的許多方面都是必不可少的,包括測試、文檔編寫、優化、條件編譯等。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/X7SqXZM18ZuKIF0bsWJCew