在 Rust 1.14 中,Index
trait定义如下:
pub trait Index<Idx> where Idx: ?Sized {
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
Output
类型的隐式 Sized
界限在这里被 ?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!
}
Idx
类型参数的隐式绑定(bind)也放宽了并且可以取消大小。但是 Idx
被值用作方法参数并且使用未确定大小的类型作为参数是不可能的 AFAIK。 为什么 Idx
允许取消大小?
最佳答案
我很确定这只是历史的偶然。那个更宽松的界限was introduced in 2014 .那个时候 trait 看起来有点不一样:
// 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;
}
请注意,此时 Index
类型是通过引用 传递的。稍后在 renamed Idx
type changed to pass by value :
fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
但是,请注意,这两种 形式共存于不同的编译器引导阶段。这可能就是为什么不能立即删除可选的 Sized
绑定(bind)的原因。 我的猜测,由于更重要的变化,它基本上被遗忘了,现在我们就在原地。
这是一个有趣的思想实验来决定限制边界(通过删除 ?Sized
)是否会破坏任何东西......也许有人应该提交 PR......^_^
思想实验结束! Lukas submitted a PR !有人讨论说它可能会破坏创建 Index
子特征的下游代码,例如:
use std::ops::Index;
trait SubIndex<I: ?Sized>: Index<I> { }
还有人说有一天,我们可能希望按值传递动态大小类型 (DST),尽管我不明白如何实现。
关于rust - 为什么 `Idx` 特征的 `Index` 类型参数允许取消大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41513631/