将集合视为智能指针

说明

使用集合的Deref特性使其像智能指针一样,提供数据的借用或者所有权。

例子

use std::ops::Deref;

struct Vec<T> {
    data: T,
    //..
}

impl<T> Deref for Vec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        //..
    }
}

一个Vec<T>是一些 T类型的所有权的集合,一个&[T]切片借用了一部分T。为Vec类型实现Deref特性使其可以隐式的 从 &Vec<T>转为&[T] ,并且也包括自动解引用的关系搜索。Vec类型大多数方法也对切片适用。

See also String and &str.

出发点

所有权和借用是Rust语言的核心概念。数据结构必须对这些语法的使用负责才能给用户一个良好的体验。当实现一个拥有数据的数据结构时,提供一个数据借用的接口将带来更大的灵活性。

优点

大部分方法可以只针对借用类型实现,这些实现对自有数据的类型可以隐式地适用。 给用户一个获取借用或所有权的选择。

缺点

边界检查时,不考虑仅通过解引用可用的方法和特性,所以对泛型数据结构使用这种模式将会变得复杂。(请看 BorrowAsRef特性)

讨论

智能指针和数据集合有相似之处:一个智能指针指向一个对象,一个集合指向许多个对象。从类型系统的角度来看二者有一点区别。一个数据集合拥有数据所有权,也负责删除数据。(包括共享数据所有权,一些借用可能是占用数据的)。一个数据集合如果拥有数据,那么通常来说会提供一个数据的借用方法以便多方使用数据。

大多数智能指针(如 Foo<T>)实现了Deref<Target=T>特性。然而数据集合常常解引用为一个自定义类型。[T]str类型有一些语言支持, 但是通常情况下,这不是必要的。即使Bar时一个动态大小的类型时,Foo<T>也可以实现Deref<Target=Bar<T>>, 并且&Bar<T> 是借用Foo<T>类型数据。

一般来讲,有序数据集合将会实现IndexRange特性来提供切片语法。其将生成借用。

参阅

Deref polymorphism anti-pattern.

Documentation for Deref trait.