Rust的属性

一、什么是属性

Attributes,属性,这个名词可在不少的语言中都有。属性有不同的表述的含义,比如常见的Getter和Setter,此类属性在Java、c#等语言中都广泛存在。另外一种就是将要讨论的作为一种元数据(Meta)的表述,是一种通用的用于表达元数据的特性,借鉴ECMA-334(C#)的语法来实现ECMA-335中描述的Attributes。在Rust中,属性只能应用于Item(元素、项)。

二、Rust属性

Rust属性的基本格式如下:

#[name(arg1, arg2 = "param")] //比如前文FFI中的#[no_mangle]表示关闭Rust的更名机制  #[test]表示这是测试

它是由一个#开启,后面紧接着一个[],里面便是属性的具体内容,它可以有如下几种写法:

单个标识符代表的属性名,如#[unix]
单个标识符代表属性名,后面紧跟着一个=,然后再跟着一个字面量(Literal),组成一个键值对,如#[link(name = “openssl”)]
单个标识符代表属性名,后面跟着一个逗号隔开的子属性的列表,如#[cfg(and(unix, not(windows)))]
在#后面还可以紧跟一个!,比如#![feature(box_syntax)],这表示这个属性是应用于它所在的这个Item。而如果没有!则表示这个属性仅应用于紧接着的那个Item。

前面提到了,在Rust中属性只能用于Item,它有以下七个主要用途::

1、条件编译代码
2、设置 crate 名称、版本和类型
3、禁用 lint 警告
4、启用编译器的特性(如宏、全局导入等)
5、连接到一个非 Rust 语言的库
6、标记函数作为单元测试
7、标记函数作为基准测试的某个部分

表现在Rust中可以在模块、crate 或者项中进行应用:
在整个 crate 应用的语法为:

#![crate_attribute] (有感叹号!)

在模块或者项应用的语法为:

#[item_attribute] (无感叹号)

属性可以接收参数,其语法形式如下:

#[attribute = "value"]
#[attribute(key = "value")]
#[attribute(value)]
#[attribute(value1, value2, value3, value4, value5)]

明白了规则再学习就很简单了。

三、应用

在Rust中,属性的应用非常广泛,主要的应用场景有:
1、extern crate声明
2、use声明
3、模块(模块是一个Item的容器)
4、函数
5、type定义
6、结构体定义
7、枚举类型定义
8、常量定义
9、静态变量定义
10、Trait定义
11、实现(Impl)
这里只对个别的进行实例说明,更具体的请参考一下Rust的相关说明文档.

// 为这个crate开启box_syntax这个新特性
#![feature(box_syntax)]
// 这是一个单元测试函数
#[test]
fn test_foo() {
    /* ... */
}
// 条件编译,只会在编译目标为Linux时才会生效
#[cfg(target_os="linux")]
mod bar {
    /* ... */
}
// 为以下的这个type定义关掉non_camel_case_types的编译警告
#[allow(non_camel_case_types)]
type int8_t = i8;
//应用于FFI
#[link(name = "readline")]
extern {
}
#[link(name = "CoreFoundation", kind = "framework")]
extern {
}

//应用于宏
#[macro_use(debug, trace)]
extern crate log;
//应用于函数

// 把`my_main`作为主函数
#[main]
fn my_main() {
}
// 把`plugin_registrar`作为此编译器插件的入口函数
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("rn", expand_rn);
}
// 把`entry_point`作为入口函数,不再执行标准库中的初始化流程
#[start]
fn entry_point(argc: isize, argv: *const *const u8) -> isize {
}
// 定义一个单元测试
// 这个单元测试一定会panic
#[test]
#[should_panic]
fn my_test() {
    panic!("I expected to be panicked");
}
// 这个函数很可能是不会执行的,
// 所以优化的时候就换种方式
#[cold]
fn unlikely_to_be_executed() {
}

其它的都可以在Rust社区和相关文档书籍中查找。

  • 代码主要来自《Rust Primer》

四、总结

如果纵向学习概念不清晰,总是分不清来龙去脉,可以考虑横向比较一下,有比较才会更精准的把握不同。就和人的漂亮和丑一样,是个相对概念,没有对比,就不会有伤害。
努力吧,归来的少年!
在这里插入图片描述

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值