设计模式
把集合当成智能指针
Description
使用Deref trait将集合视为智能指针,提供拥有和借用的数据视图。
Example
考虑Vec,Vec是一个拥有T的集合,然后通过实现Deref完成&Vec到&[T]的隐式解引用,从而提供借用T的集合(即&[T])。
impl<T> Deref for Vec<T> {type Target = [T];fn deref(&self) -> &[T] {unsafe {std::slice::from_raw_parts(self.ptr.as_ptr(), self.len)}}}
原因:Vec提供了拥有T的集合,&[T]提供借用T的集合。大部分情况下,只需要借用视图,提供两种方式,让用户在使用时在借用和拥有之间做出选择。
Discussion
智能指针和集合是类似的:一个智能指针指向一个对象,而一个集合指向许多对象。 从类型系统的角度来看,这两者之间没有什么区别。 如果访问每个数据的唯一途径是通过集合,并且集合负责删除数据(即使在共享所有权的情况下,某种借用视图可能是合适的),那么集合就拥有它的数据。 如果集合拥有它的数据,提供借用数据的视图通常是有用的,这样它就可以被多次引用了。
大多数智能指针(例如,Foo<T>)实现了Deref<Target=T>。 然而,集合通常会解引用到一个自定义的类型。 [T]和str有一些语言支持,但在一般情况下,这是没有必要的。 Foo<T>可以实现Deref<Target=Bar<T>,其中Bar是一个动态大小的类型,&Bar<T>是对Foo<T>中数据的借用视图。
通常,有序集合为Range实现Index,以提供分片语法。目标是借用视图。