用于处理借用数据的模块: std::borrow
1 Borrow
#![allow(unused)]
fn main() {
pub trait Borrow<Borrowed>
where
Borrowed: ?Sized,
{
// Required method
fn borrow(&self) -> &Borrowed;
}
}
一个用于借用数据的trait.
通过实现Borrow<T>来表达它们可以作为其个类型T借出.并在trait的borrow方法中提供对T的引用.
例如: String实现了Borrow<str>,则可以作为str进行借出, Box<T>实现了Borrow<T>,则可以作为T进行借出
2. BorrowMut
#![allow(unused)]
fn main() {
pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
where
Borrowed: ?Sized,
{
// Required method
fn borrow_mut(&mut self) -> &mut Borrowed;
}
}
一个用于可变借用数据的trait.
作为Borrow<T>的补充,该trait允许类型通过提供可变引用来借用底层类型.
3. ToOwned
#![allow(unused)]
fn main() {
pub trait ToOwned {
type Owned: Borrow<Self>;
// Required method
fn to_owned(&self) -> Self::Owned;
// Provided method
fn clone_into(&self, target: &mut Self::Owned) { ... }
}
}
Clone在借用数据上的泛化.
Clone一般是&T到T, ToOwned trait 将Clone泛化, 可以从给定类型的任何借用中构造拥有数据.
这里关联类型Owned需要满足Borrow<Self> trait, 此处Self为要实现ToOwned的结构.
看下 str对ToOwned trait 的实现:
#![allow(unused)]
fn main() {
impl ToOwned for str {
type Owned = String
// Required method
fn to_owned(&self) -> Self::Owned { ... }
// Provided method
fn clone_into(&self, target: &mut Self::Owned) { ... }
}
}
关联类型Owned被定义为String, 而根据要求,String必须定义Borrow<T>,那这里Borrow里的泛型变量T是谁呢?ToOwned要求是Borrow<Self>,而此刻实现 ToOwned 的主体是 str,所以 Borrow<Self> 是 Borrow<str>, 而String的确实现了Borrow<str>.
4. Cow
#![allow(unused)]
fn main() {
pub enum Cow<'a, B>
where
B: 'a + ToOwned + ?Sized,
{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
}
Cow用于提供写时克隆(Clone-on-Write)的一个智能指针,包裹一个只读借用,但如果调用者需要所有权或者需要修改内容,那么它会 clone 借用的数据.
Cow实现了Deref trait.
#![allow(unused)]
fn main() {
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B> {
type Target = B;
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Owned(ref owned) => owned.borrow(),
}
}
}
}