rust学习3-派生-derive


派生

通过 #[derive] 属性,编译器能够提供某些 trait 的基本实现。如果需要更复杂的行为,这些 trait 也可以手动实现。

下面是可以自动派生的 trait:

  • 比较 trait: Eq, PartialEq, Ord, PartialOrd
    • Eq:完全等价关系
    • PartialEq: 部分等价关系
    • Ord:全序关系
    • PartialOrd:比较排序顺序的值
  • Clone, 用来从 &T 创建副本 T
  • Copy,使类型具有 “复制语义”(copy semantics)而非 “移动语义”(move semantics)。
  • Hash,从 &T 计算哈希值(hash)。
  • Default, 创建数据类型的一个空实例。
  • Debug,使用 {:?} formatter 来格式化一个值。
// `Centimeters`,可以比较的元组结构体
#[derive(PartialEq, PartialOrd)]
struct Centimeters(f64);

// `Inches`,可以打印的元组结构体
#[derive(Debug)]
struct Inches(i32);

impl Inches {
    fn to_centimeters(&self) -> Centimeters {
        let &Inches(inches) = self;

        Centimeters(inches as f64 * 2.54)
    }
}

// `Seconds`,不带附加属性的元组结构体
struct Seconds(i32);

fn main() {
    let _one_second = Seconds(1);

    // 报错:`Seconds` 不能打印;它没有实现 `Debug` trait
    //println!("One second looks like: {:?}", _one_second);
    // 试一试 ^ 取消此行注释

    // 报错:`Seconds`不能比较;它没有实现 `PartialEq` trait
    //let _this_is_true = (_one_second == _one_second);
    // 试一试 ^ 取消此行注释

    let foot = Inches(12);

    println!("One foot equals {:?}", foot);

    let meter = Centimeters(100.0);

    let cmp =
        if foot.to_centimeters() < meter {
            "smaller"
        } else {
            "bigger"
        };

    println!("One foot is {} than one meter.", cmp);
}

属性

属性是应用于某些模块、crate 或项的元数据(metadata)。这元数据可以用来:

  • 条件编译代码
  • 设置 crate 名称、版本和类型(二进制文件或库)
  • 禁用 lint (警告)
  • 启用编译器的特性(宏、全局导入(glob import)等)
  • 链接到一个非 Rust 语言的库
  • 标记函数作为单元测试
  • 标记函数作为基准测试的某个部分

当属性作用于整个 crate 时,它们的语法为 #![crate_attribute],当它们用于模块 或项时,语法为 #[item_attribute](注意少了感叹号 !)。

属性可以接受参数,有不同的语法形式:

  • #[attribute = "value"]
  • #[attribute(key = "value")]
  • #[attribute(value)]

属性可以多个值,它们可以分开到多行中:

#[attribute(value, value2)]

#[attribute(value, value2, value3,
            value4, value5)]

你可能感兴趣的:(技术向,rust)