将集合视为智能指针
说明
使用集合的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语言的核心概念。数据结构必须对这些语法的使用负责才能给用户一个良好的体验。当实现一个拥有数据的数据结构时,提供一个数据借用的接口将带来更大的灵活性。
优点
大部分方法可以只针对借用类型实现,这些实现对自有数据的类型可以隐式地适用。 给用户一个获取借用或所有权的选择。
缺点
边界检查时,不考虑仅通过解引用可用的方法和特性,所以对泛型数据结构使用这种模式将会变得复杂。(请看 Borrow和AsRef特性)
讨论
智能指针和数据集合有相似之处:一个智能指针指向一个对象,一个集合指向许多个对象。从类型系统的角度来看二者有一点区别。一个数据集合拥有数据所有权,也负责删除数据。(包括共享数据所有权,一些借用可能是占用数据的)。一个数据集合如果拥有数据,那么通常来说会提供一个数据的借用方法以便多方使用数据。
大多数智能指针(如 Foo<T>)实现了Deref<Target=T>特性。然而数据集合常常解引用为一个自定义类型。[T]和str类型有一些语言支持,
但是通常情况下,这不是必要的。即使Bar时一个动态大小的类型时,Foo<T>也可以实现Deref<Target=Bar<T>>,
并且&Bar<T> 是借用Foo<T>类型数据。
一般来讲,有序数据集合将会实现Index 和Range特性来提供切片语法。其将生成借用。