为什么`Index`特征的`Idx`类型参数可以被取消?

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)

这里放宽SizedOutput类型的隐式绑定?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允许不合格?

She*_*ter 6

我很确定这只是历史事故.更宽松的约束是在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),尽管我不明白如何.

  • 像往常一样很棒的答案 (3认同)
  • *还有人说,有一天,我们可能希望按值传递动态大小的类型(DST),虽然我不明白如何.*=>语言和实现之间存在差异.仅仅因为语言认为它是一个移动(按值传递)并不意味着在ABI级别,该值不会被指针传递.因此,语言通过值传递DST是非常明智的,实际实现是使用指针.然而,按价值返回它们似乎更棘手:) (2认同)