集册 Rust 语言中文版 Borrow 和 AsRef

Borrow 和 AsRef

欢马劈雪     最近更新时间:2020-08-04 05:37:59

197

Borrow 和 AsRef 特性是非常相似的,但是也有些区别。这里有一个简单回顾一下这两个特质是什么意思。

Borrow

Borrow 特性是当你写一个数据结构时,并且你想要使用一个 owned 或 borrowed 类型作为用于某些目的的同义词。

例如,HashMap 的 get 方法就使用了 Borrow:

 fn get<Q: ?Size>(&self, k:&Q) -> Option<&V>
    where K:Borrow<Q>,
          Q:Hash +Eq

这个签名是相当复杂的。在这里我们感兴趣的是 K 参数。它指的是 HashMap 本身的一个参数:

struct HashMap<K, V, S = RandomState> {

K 参数是 HashMap 中使用的 key 类型。所以,再次看 get() 函数签名,当 key 实现了 Borrow 时我们可以使用 get() 函数。这样,我们可以使用 String 类型作为 HashMap 的 key,而使用 &strs 进行搜索:

use std::collections::HashMap:

let mut map = HashMap::new();
map.insert("Foo".to_string(), 42);

assert_eq!(map.get("Foo"), Some(&42));

这是因为标准库中已经为 String 类型实现了 Borrow 接口。

对于大多数类型,当你想要一个使用 owned 或者 borrowed 类型,使用 &T 就足够了。但在不止一种 borrowed 值时,Borrow 处理起来是很高效的。Slice 指的是一块区域:既可以是 &[T]也可以是 &mut[t] 类型。如果我们想使该区域同时存在着两种类型,就可以使用 Borrow:

use std::borrow::Borrow;
use std::fmt::Display;

fn foo<T: Borrow<i32> + Display>(a: T) {
    println!("a is borrowed: {}", a);
}

let mut i = 5;

foo(&i);
foo(&mut i);

上面的代码会输出 a is borrowed: 5 两次。

AsRef

AsRef 是转换特征。它被用在通用的代码中将一些值转换成索引类型。比如:

展开阅读全文