Rust中的切片索引是如何工作的?

3

我想知道 Rust 中的“slices”是什么。结果发现,它只是一个带有数据指针和大小的结构体。我查看了索引源代码,并且找到了这个

impl<T> ops::Index<usize> for [T] {
    type Output = T;

    fn index(&self, index: usize) -> &T {
        // NB built-in indexing
        &(*self)[index]
    }
}

我不是Rust专家,但&(*self)对我来说似乎是一个指针,并且据我所知,在Rust中没有指针索引。那么这个索引是如何工作的呢?它只是编译器内置的东西吗?


1
@LukasKalbertodt 抱歉,已经编辑! - Peter Lenkefi
1个回答

2
这只是编译器内置的东西吗?
是的。源代码注释也是这样说的。[T]是一种无大小类型,需要一些额外的规则。例如,无大小类型不能存储在栈上(很难处理)。但是对于无大小类型的引用,它们由指针和大小组成(具体来说,“完成”类型的“某些东西”)。
但是请注意,表达式的计算方式如下:&((*self)[index])。这意味着self(类型为&[T])被解除引用为类型[T],然后进行索引。这将返回一个T,但我们只想要一个对它的引用,因此有了&符号。

1
说实话,我一直觉得这个索引返回值并且需要添加 & 的想法很奇怪。我的直觉告诉我:为什么要取一个临时变量的引用呢? - Matthieu M.
1
索引生成一个左值,这与临时值(右值)完全相反。 - Sebastian Ullrich
@Kha:不幸的是,错误信息并不是这样说的:它抱怨v [0]返回一个String,因此是一个(新鲜的)值。我知道情况并非如此,但我仍然觉得这真的很令人困惑。(也许这只是一个改进诊断将大大澄清事情的案例)。 - Matthieu M.
1
@MatthieuM。'returning'确实会让人困惑...但它并没有这么说。v[0]是类型为String的(非临时l-)值,这完全正确。我不确定如何改进这个消息。 - Sebastian Ullrich
1
@Kha:我也不确定。只是因为从解引用中获取的“值”与新值之间的差异可能会很明显,因为在后者上,您可以通过应用&“返回”到原始引用,而在前者上,除非编译器决定有所帮助并延长基础值的生命周期,否则应用&通常不起作用(由于生命周期)。这对初学者来说可能是个小问题,我不知道该如何解决它。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接