Borrow 和 AsRef 特性是非常相似的,但是也有些区别。这里有一个简单回顾一下这两个特质是什么意思。
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 是转换特征。它被用在通用的代码中将一些值转换成索引类型。比如:
let s = "Hello".to_string();
fn foo<T: AsRef<str>>(s: T) {
let slice = s.as_ref();
}
我们可以看到他们是如何的相似:他们都处理 owned 和 borrowed 版本的数据类型。然而,他们还是有点不同。
当你想要抽象出各种 borrowing 数据中的不同,或者你创建的数据结构用同样的方式对待 owned 和 borrowed 值,比如哈希操作和比较操作,此时你应该选择 Borrow。
当你想要直接转换某些类型为引用类型,并且你在编写泛型时,你应该选择 AsRef。
方法语法函数很好,但是如果你想要在一些数据上调用很多函数,那是非常不合适的。请思考以下代码: baz(bar(foo)));我们从左往右...
当一个向量中的元素过多,同时向量的各元素有等差的规律,此时采用直接输入法将过于繁琐。针对该种情况 ,可以使用冒号(:) 来生...
分析宏代码所有宏过程都以关键词“Sub”开始,以关键词“End Sub”结束。在关键词“Sub”之后是宏的真正的名字,然后紧跟着是一...
ASP.NET Button ValidationGroup 属性 Button 控件定义和用法 ValidationGroup 属性规定在 Button 控件回发到服务器时要进行验证...