Rust : Attribute 屬性 作者:Mike Tang

【Rust每週一知】 Attribute 屬性
原創 Mike Tang Rust語言中文社區 3天前

屬性是作用在 Rust 語言元素上的元數據。

Rust 中的屬性數量非常多。而且具有可擴展性(可自定義屬性)。Rust 的屬性語法遵從 C# 定義並標準化了的屬性規範ECMA-334。

Rust 代碼中隨處可見屬性,有時甚至會多得讓人摸不着頭腦。本篇是對 Rust 中的屬性相關知識的簡單總結。水平有限,僅起到拋磚引玉的作用。
概念

整體來講,屬性還是比較好理解的,但是需要先理解一些基本概念:
Inner Attributes(內部屬性) 和 Outer Attributes(外部屬性)

內部屬性(Inner Attribute)是指:一個屬性聲明在一個元素中,對此元素(比如一般爲 crate)整體生效。內部屬性用 #![] 聲明。

外部屬性(Outer Attribute)是指:一個屬性聲明在一個元素之前,對跟在後面的這個元素生效。外部屬性用 #[] 聲明。

Rust 中,有些屬性可以/只能作內部屬性使用,有些屬性可以/只能作外部屬性使用。

Meta Item Attribute Syntax

Meta Item Attribute Syntax 實際上描述了屬性語法的基本結構。

下面表格羅列了所有 Meta Item Attribute Syntax。第一列是語法樣式名稱,第二列是語法看起來的樣子。

在這裏插入圖片描述

我們在 Rust 代碼中看到的所有屬性語法都是上述五種中的一種或其組合。

Active 和 insert 屬性

一個屬性,要麼是 active 的,要麼是 insert 的。

Active 屬性是指,在處理屬性(預處理代碼)的過程中,active 屬性會將它們自己刪除,留下所作用的元素。

Insert 屬性是指,在處理屬性(預處理代碼)的過程中,insert 屬性會將它們自己保留。

cfg 和 cfg_attr 屬性是 active 的。

當編譯爲 test 模式時,test 屬性是 insert 的。編譯爲非 test 模式時,test 屬性是 active 的。

屬性宏是 active 的。

所有其它屬性是 insert 的。

屬性的分類

Rust 中的屬性,可以分爲以下四大類。

Macro attributes - 宏屬性

Derive macro helper attributes - 派生宏輔助屬性

Tool attributes - 工具屬性

Built-in attributes - 內建屬性

Macro Attributes 宏屬性

宏屬性,也叫屬性宏。屬於過程宏的一種。

定義過程宏的時候,使用 #[proc_macro_attribute],加一個固定簽名的函數(詳見過程宏一章)。

#[proc_macro_attribute]
pub fn return_as_is(_attr: TokenStream, item: TokenStream) -> TokenStream {
	item
}

使用過程宏:

#[return_as_is]
fn invoke() {}

Derive macro helper attributes 派生宏輔助屬性

派生宏輔助屬性,聽起來有點拗口,其實它是這樣一個東西:

先定義派生宏

#[proc_macro_derive(HelperAttr, attributes(helper))]
pub fn derive_helper_attr(_item: TokenStream) -> TokenStream {
TokenStream::new()
}

看如何使用:

#[derive(HelperAttr)]
struct Struct {
	#[helper] field: ()
}

裏面那個 #[helper] 就是一個派生宏輔助屬性。

Tool Attributes 工具屬性

工具屬性。Rust 還允許外部工具定義它們自己的屬性,並且在獨立的命名空間下面。比如:

// Tells the rustfmt tool to not format the following element.
#[rustfmt::skip]
struct S {
}

// Controls the "cyclomatic complexity" threshold for the clippy tool.
#[clippy::cyclomatic_complexity = "100"]
pub fn f() {}

不過如果你想在自己的工具中定義 Tool Attribute,那就想多了。現在 rustc 只認識兩個外部工具(及它們內部的屬性):一個是 rustfmt,另一個是 clippy。

Built-in Attributes 內建屬性

4 種屬性的前面兩種:宏屬性和派生宏輔助屬性,是可以完全自定義的。後面兩種:工具屬性和內建屬性,我們只能用,不能自定義。

Rust 內建了 14 類屬性。OMG @_@!!

每一個屬性都有自己的用法,有的用法還比較多,可以用到的時候,再去查閱。這裏簡單羅列說明一下。

條件編譯

    cfg

    cfg_attr

測試

    test

    ignore

    should_panic

派生

    derive

宏相關

    macro_export

    macro_use

    proc_macro

    proc_macro_derive

    proc_macro_attribute

診斷

    allow, warn, deny, forbid - lint 相關標誌開關,各種 lint 見附錄。

    deprecated

    must_use

ABI, 鏈接, 符號, 和 FFI

    link

    link_name

    no_link

    repr

    crate_type

    no_main

    export_name

    link_section

    no_mangle

    used

    crate_name

代碼生成

    inline

    cold

    no_builtins

    target_feature

文檔

    doc

預引入

    no_std

    no_implicit_prelude

模塊

    path

限制

    recursion_limit

    type_length_limit

運行時

    panic_handler

    global_allocator

    windows_subsystem

語言特性

    feature - 經常會碰到這裏面一些陌生的 feature 名稱,需要根據具體的 rustc 版本和所使用的庫文檔進行查閱。

類型系統

    non_exhaustive

上面的屬性中,很多屬性,其內容都可以單獨開一篇文章來講解。比如,條件編譯相關的屬性,FFI 相關屬性等。
參考

本文內容主要來自:https://doc.rust-lang.org/reference/attributes.html。 加入了作者的一些理解。各位同學有時間的話,最好將上述文檔中的內容每一個都仔細過一遍。這樣,需要用到的時候,溫習一下就會用了。也並不是太難的事兒。

Unstable Book 對 rustc 的 flags 和各種 features 都做了詳細的說明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章