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》

四、总结

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

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Rust 中, `impl` 块用于定义类型的方法。在这些方法中, `self` 是表示当前类型实例的关键字, 它有三种不同的属性: - `self`: 表示不可变的当前类型实例的引用。 - `&self`: 表示可变的当前类型实例的引用。 - `&mut self`: 表示独占的可变的当前类型实例的引用。 其中,用 self 代表的是不可变的引用, 如果需要对实例进行修改, 那么需要使用 &mut self 代表可变引用。 这是 Rust 中访问控制的方式,保证了程序运行时的线程安全。 ### 回答2: 在 Rust 中,`impl` 代码块中的 `self` 关键字用于表示实现类型本身的一个实例。实际上,`self` 作为方法的隐式参数,允许我们在对类型进行操作时访问它的属性和方法。 `self` 可以具备以下几种属性: 1. `self` 可以是一个值类型 `self: Self`,其中 `Self` 是实现类型本身的关联类型。例如,对于一个结构体类型 `Person` 的实现类型 `impl Person`,`self` 就是 `Person` 的一个实例,我们可以通过 `self` 来访问 `Person` 的所有属性和方法。 2. `self` 可以是一个可变引用类型 `self: &mut Self`,其中 `Self` 是实现类型本身的可变引用。这种情况下,我们可以通过 `self` 来改变实现类型的属性值。 3. `self` 可以是一个不可变引用类型 `self: &Self`,表示 `Self` 的不可变引用。这种情况下,我们可以通过 `self` 来访问实现类型的属性,但不能对其进行修改。 除了以上几种,Rust 还支持其他用法来表示 `self` 的属性,例如 `self: Box<Self>` 表示 `self` 是一个实现类型的堆分配对象的所有权,`self: Rc<Self>` 表示 `self` 是一个引用计数对象的引用,等等。 总之,通过 `self` 关键字,我们可以在 `impl` 块中访问实现类型的属性和方法,并且根据需要,还可以对其进行修改或获取所有权。这为我们在 Rust 中编写可靠和高效的代码提供了很大的灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值