Rust常用特型之Default特型

在Rust标准库中,存在很多常用的工具类特型,它们能帮助我们写出更具有Rust风格的代码。

某些类型可以有一个有意义的默认值,例如默认的向量或者字符串是空的,默认的数字为0,默认的Option是None等。

这样的类型可以实现std::default::Default特型:

trait Default {
fn default() -> Self;
}

该特型很简单,就只有一个关联函数default,用于返回自身类型的一个新的值。

我们来看字符串String对该特型的实现,非常简单:

impl Default for String {
fn default() -> String {
  String::new()
  }
}

所以字符串的默认值就是一个新的空字符串.所有Rust的集合类型,Vec,HashMap,BinaryHeap等,都实现了Default特型,它们的default函数返回一个空的集合。这在你需要先建立一个集合,以后再向里面插入值时非常有用,因为你建立集合时不需要指定其中元素的类型,在第一次插入值时决定。

例如 Iterator特型的partition函数 把迭代器产生的值分离成两个集合,它使用一个闭包函数来决定哪个值去哪个集合。

use std::collections::HashSet;
let squares = [4, 9, 16, 25, 36, 49, 64];
let (powers_of_two, impure): (HashSet<i32>, HashSet<i32>)
  = squares.iter().partition(|&n| n & (n-1) == 0);
assert_eq!(powers_of_two.len(), 3);
assert_eq!(impure.len(), 4);

闭包函数使用位操作符来查找哪些数是2的幂,partition函数使用它产生两个HashSet。当然,partition函数并不是只能产生HashSet,你可以使用它产生任何类型的集合,只要该集合实现了DefaultExtend<T>特型,前者它会产生一个新的空集合,后者是将产生的值添加到集合中去。String 也实现了DefaultExtend<char>特型,因此你可以这样写:

let (upper, lower): (String, String)
  = "Great Teacher Onizuka".chars().partition(|&c|c.is_uppercase());
assert_eq!(upper, "GTO");
assert_eq!(lower, "reat eacher nizuka");

Default特型另一个常见的应用场景为多字段结构体赋值。如果一个结构体有很多字段,但是其中绝大多数字段的值是固定的,很少变化的。因此我们构造结构体时只需要给出少数几个需要设定的字段就行了,其它的固定字段使用一个默认值就行。例如glimu::DrawParameters结构体有24个字段,每个字段都用来控制OpenGL怎么渲染图形中的某些位。而glium draw函数使用一个DrawParameters 结构体作为参数,由于它实现了Default,你可以这样写:

let params = glium::DrawParameters {
    line_width: Some(0.02),
    point_size: Some(0.02),
    .. Default::default()
};
target.draw(..., &params).unwrap();

这里我们只需要写出该结构体的两个字段 line_width和point_size,其它的都使用默认值。Default::default()会创建一个包含默认初始化值的DrawParameters结构体(这里为什么创建的值的类型是DrawParameters?因为Rust会自动推断,当然你也可以写 DrawParameters::default(),这样会多拼几个字母)。..语法是解构,和Javascript类似,就是余下的字段全部从这里获取,但是有一眯注意,它必须出现在结构体构造的最后一行(Javascript没有这个限制)。

如果一个T类型实现了Default,Rust 标准库也为Rc<T>,Arc<T>Box<T>, Cell<T>, RefCell<T>, Cow<T>, Mutex<T>

RwLock<T>自动实现了Default特型。例如,Rc<T>的默认值就是一个指向T默认值的Rc指针。如果元组的所有元素实现了Default,那么该元组(tuple)也自动实现了Default特型。它的默认值就是一个容纳了每个元素默认值的元组。

Rust 并没有为结构体自动实现Default特型。但是如果结构体所有的字段都实现了Default,那么你可以简单的在结构体定义上面添加#derive(Default)]来为该结构体自动实现Default特型。如果该结构体不符合这个条件,那么即使你手动添加了派生宏,也不会有效果。

相关推荐

  1. Rust特型Default特型

    2024-04-22 20:08:01       14 阅读
  2. Rust特型Drop特型

    2024-04-22 20:08:01       25 阅读
  3. Rust特型ToOwned特型

    2024-04-22 20:08:01       13 阅读
  4. Rust特型Sized特型

    2024-04-22 20:08:01       14 阅读
  5. Rust特型Clone+Copy特型

    2024-04-22 20:08:01       18 阅读
  6. Rust特型TryFrom和TryInto特型

    2024-04-22 20:08:01       13 阅读
  7. Rust特型AsRef和AsMut特型

    2024-04-22 20:08:01       13 阅读
  8. Rust特型From和Into特型

    2024-04-22 20:08:01       11 阅读
  9. Rust特征

    2024-04-22 20:08:01       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-22 20:08:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-22 20:08:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-22 20:08:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-22 20:08:01       20 阅读

热门阅读

  1. npm常用命令详解

    2024-04-22 20:08:01       11 阅读
  2. 生活无趣感的成因与破解之道

    2024-04-22 20:08:01       15 阅读
  3. 大数据集群中部署Hive

    2024-04-22 20:08:01       11 阅读
  4. CMake

    CMake

    2024-04-22 20:08:01      37 阅读
  5. Hive进阶Day06

    2024-04-22 20:08:01       20 阅读
  6. 达梦数据库的DMRMAN工具介绍

    2024-04-22 20:08:01       13 阅读
  7. ChatGPT写作术:高效撰写顶级论文

    2024-04-22 20:08:01       13 阅读