Borrow
Borrow<T>
在Rust中,通常为不同的用例提供不同类型的表示。例如,可以通过诸如Box <T
>或Rc <T>
之类的指针类型来特定地选择适合于特定用途的值的存储位置和管理。除了可以与任何类型一起使用的这些通用包装器之外,某些类型提供了可选的方面,提供了可能代价高昂的功能。这种类型的一个例子是String,它增加了将字符串扩展到基本str的能力。这需要为简单的不可变字符串保留额外的信息。
这些类型通过引用该数据的类型提供对底层数据的访问。他们被称为“借用”那种类型。例如,Box <T>
可以作为T借用,而String可以作为str借用。
类型表示可以通过实现Borrow <T>
将它们作为某种类型T借用,在特征的借用方法中提供对T的引用。一种类型可以免费借用几种不同的类型。如果它希望可变地借用类型 - 允许修改基础数据,它还可以实现BorrowMut
此外,当提供其他特征的实现时,需要考虑它们是否应该与基础类型的行为相同,作为作为该基础类型的表示的结果。当通用代码依赖于这些附加特征实现的相同行为时,通常使用Borrow <T>
。这些特征可能会作为额外的特征界限出现。
如果通用代码仅需要适用于可以提供对相关类型T的引用的所有类型,则通常最好使用AsRef <T>
,因为更多类型可以安全地实现它。
Borrow
提供了一个方法 .borrow()
。对于一个类型为 T
的值 foo
,如果 T
实现了 Borrow<U>
,那么,foo
可执行 foo.borrow()
。操作的结果,我们得到了一个类型为 &U
的新引用。
Borrow
可以认为是 AsRef
的严格版本,它对普适引用操作的前后类型之间附加了一些其它限制。AsRef
更通用,更普遍,覆盖类型更多。
Borrow
的前后类型之间要求必须有内部等价性。不具有这个等价性的两个类型之间,不能实现 Borrow
。
use std::borrow::Borrow;
fn check<T: Borrow<str>>(s: T) {
assert_eq!("Hello", s.borrow());
}
let s = "Hello".to_string();
check(s);
let s = "Hello";
check(s);
BorrowMut<T>
此特征允许类型通过提供可变引用而作为基础类型借用。 BorrowMut<T>
提供了一个方法 .borrow_mut()
。它是 Borrow<T>
的可变(mutable)引用版本。
对于一个类型为 T
的值 foo
,如果 T
实现了 BorrowMut<U>
,那么,foo
可执行 foo.borrow_mut()
。操作的结果我们得到类型为 &mut U
的一个可变(mutable)引用。
注:在转换的过程中,foo
会被可变(mutable)借用。
ToOwned
通过实现Clone
,某些类型可以从借用变为拥有。它提供了 .to_owned()
方法,用于类型转换。有些实现了 Clone
的类型 T
可以从引用状态实例 &T
通过 .clone()
方法,生成具有所有权的 T
的实例。但是它只能由 &T
生成 T
。而对于其它形式的引用,Clone
就无能为力了。而 ToOwned
trait 能够从任意引用类型实例,生成具有所有权的类型实例。
let s: &str = "a";
let ss: String = s.to_owned();
let v: &[i32] = &[1, 2];
let vv: Vec<i32> = v.to_owned();