rust - 为什么 `Idx` 特征的 `Index` 类型参数允许取消大小?

标签 rust language-lawyer

在 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/

相关文章:

rust - 我如何实现 std::ops::Index 来改变被索引的值?

rust - 为什么基于 len() 索引一个可变向量被认为是同时借用?

rust - 枚举类型的自定义 serde 序列化

C++ 模板类型规范

c++ - 用纯说明符覆盖虚拟函数是否有效?

c - fgets() 是否返回 NULL 并兼容短缓冲区?

c++ - 了解 declval 优化实现

常量 32768 和 0x8000 之间的类型差异会有所不同吗?

rust - 错误[E0507] : Cannot move out of borrowed content

rust - 从 if 语句中返回值时出现 "mismatched types"错误