我仔细阅读了rust的英文教程,发现了rust的属性的用法还挺有趣的
以下是我截取的使用wasm_bindgen属性的一个例子
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
以下是我摘下来的7个主要用处
- conditional compilation of code
- set crate name, version and type (binary or library)
- disable lints (warnings)
- enable compiler features (macros, glob imports, etc.)
- link to a foreign library
- mark functions as unit tests
- mark functions that will be part of a benchmark
但是这个语法对于我来说也是相当困惑,有以下两个问题
- 我可以定义自己的属性吗?
- 从编译层面它是怎么起作用的,有源代码之类的看吗?
1
共 4 条评论, 1 页
评论区
写评论stable是rustc对内置库(std,core,alloc,proc_macro)使用的一个属性,会被rustc解析,表面这个功能是在某版本号之后稳定的,对应的还有unstable,只有当rustc是nightly版本时并且使用#![feature()]才能使用unstable的功能. 所有未稳定的功能在https://doc.rust-lang.org/nightly/unstable-book/the-unstable-book.html
另外,我还有一个疑问,我翻看了proc_macro的源码,看到了一下一个属性
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
我在下面的文档后面列出的所有内建属性中没有找到 stable的定义 https://doc.rust-lang.org/reference/attributes.html
所以,这个是自定义的属性吗
感谢楼上的回复,是我理解错了,内建的属性和那个#[wasm_bindgen]是有本质区别的,后者是宏的一种,我又看了文档,原来过程宏有三种,也就是楼上说的那三种,用我自己的话来理解就是 像函数一样的宏(就是后面带了感叹号那种,就像println!),一种就是我上面理解错的那种:像属性一样的宏,第三种我还没有见过,我理解是自定义的衍生宏,不知道还有人可以给一下具体使用它的例子吗?
我还摘了一些源码出来
再次感谢楼上的回复!
你说的7个功能是rustc内置的,和#[wasm_bindgen]这种不是一回事.
#[wasm_bindgen]这种自定义的属性属于过程宏(proc-macro),是rustc的一个功能(严格地说不是rust语言的语法)
过程宏位于单独的crate中(Cargo.toml中有proc-macro = true),被编译成链接到rustc的so/dll,编译源代码的时候被rustc加载,然后处理被修饰的AST(即proc_macro::TokenStream类型),返回处理后的AST,然后rustc继续编译.
理论上过程宏可以把被修饰的源代码修改成任意想要的代码
rustc内置一个proc-macro,就像core和std一样.proc-macro提供了编写新的过程宏的接口,以及rust token类型的定义,文档在https://doc.rust-lang.org/proc_macro/
过程宏的crate里需要定义处理TokenStream的函数,这些函数本身需要被一些属性修饰,表面他们的使用方式
使用方法是
要写一个过程宏可以参考: syn,quote,proc-macro2 这些crate,因为内置的proc-macro功能很少
proc-macro2是第三方库,能在不同编译器版本之间保证proc-macro的兼容性
syn能把proc_macro::TokenStream解析成自定义的struct,qutoe实现了类似macro_rules!的语法,但是返回的结果是TokenStream
wasm_bindgen的源码在:
https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro
https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro-support