Luk*_*odt 7 language-lawyer rust
在Rust 1.14中,Index
特征定义如下:
pub trait Index<Idx> where Idx: ?Sized {
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
Run Code Online (Sandbox Code Playgroud)
这里放宽Sized
了Output
类型的隐式绑定?Sized
.这是有道理的,因为该index()
方法返回一个引用Output
.因此,可以使用未实现的类型,这是有用的; 例:
impl<T> Index<Range<usize>> for Vec<T> {
type Output = [T]; // unsized!
fn index(&self, index: Range<usize>) -> &[T] { … } // no problem: &[T] is sized!
}
Run Code Online (Sandbox Code Playgroud)
该Idx
类型参数的隐式绑定也轻松,可以无胶.但是Idx
作为方法参数使用值,并且使用未定义类型作为参数是不可能的AFAIK.为什么Idx
允许不合格?
我很确定这只是历史事故.更宽松的约束是在2014年推出的.那个时候,这个特质看起来有点不同:
// Syntax predates Rust 1.0!
pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}
Run Code Online (Sandbox Code Playgroud)
请注意,此时,Index
类型是通过引用传递的.稍后,重命名的Idx
类型更改为按值传递:
fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
Run Code Online (Sandbox Code Playgroud)
但请注意,两种形式在不同的编译器引导阶段共存.这可能是为什么Sized
无法立即删除可选绑定的原因.这是我的猜测,由于更重要的变化,它基本上被遗忘了,现在我们就在这里.
这是一个有趣的思想实验来决定限制界限(通过删除?Sized
)是否会破坏任何东西......也许有人应该提交PR ... ^ _ ^
想过实验!卢卡斯提交了公关!有人一直在讨论它可能会破坏下游代码,这些代码会产生以下Index
类似的子特征:
use std::ops::Index;
trait SubIndex<I: ?Sized>: Index<I> { }
Run Code Online (Sandbox Code Playgroud)
还有人说,有一天,我们可能希望按值传递动态大小的类型(DST),尽管我不明白如何.