将集合视为智能指针
说明
使用集合的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
特性来提供切片语法。其将生成借用。