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 是转换特征。它被用在通用的代码中将一些值转换成索引类型。比如: