用于处理借用数据的模块: 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借出.并在traitborrow方法中提供对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一般是&TT, 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(),
        }
    }
}
}