给定 v = vec![1,2,3,4]
,为什么 v [4..]
返回一个空向量,但是 v [5..]
报错了,而 v [4]
和 v [5]
都会报错?我怀疑这与在不指定起点或终点的情况下对切片进行实现有关,但我找不到任何在线信息。
给定 v = vec![1,2,3,4]
,为什么 v [4..]
返回一个空向量,但是 v [5..]
报错了,而 v [4]
和 v [5]
都会报错?我怀疑这与在不指定起点或终点的情况下对切片进行实现有关,但我找不到任何在线信息。
std::ops::RangeFrom
的定义是“下界包含”,即使它没有上界限制。简单回顾一下所有的管道: v[4..]
解糖成std::ops::Index
,使用4..
(解析为std::ops::RangeFrom
)作为参数。std::ops::RangeFrom
实现了std::slice::SliceIndex
,而且Vec
对于任何实现std::slice::SliceIndex
的参数都有实现了std::ops::Index
。所以你看到的是使用RangeFrom
来std::ops::Index
Vec
。
std::ops::RangeFrom
被定义为始终包含下界,例如[0..]
将包括要索引的第一个元素。如果(在你的情况下)Vec
为空,则[0..]
将是空片段。注意:如果下界不包含,则没有办法切片一个空的Vec
而不会导致恼人的紧急情况。
一个简单的思考方法是“栅杆放在哪里”。
vec![0, 1, 2, 3]
中的v [0..]
是
| 0 1 2 3 |
^
|- You are slicing from here. This includes the
entire `Vec` (even if it was empty)
在v [4..]
中
| 0 1 2 3 |
^
|- You are slicing from here to the end of the Vector.
Which results in, well, nothing.
如果使用 v[5..]
,则会是
| 0 1 2 3 |
^
|- Slicing from here to infinity is definitely
outside the `Vec` and, also, the
caller's fault, so panic!
而 v[3..]
是
| 0 1 2 3 |
^
|- slicing from here to the end results in `&[3]`
v = vec![1,2,3,4]
,为什么v[4..]
返回一个空向量,但v[5..]
会发生错误[..]?fn index(self, slice: &[T]) -> &[T] {
if self.start > slice.len() {
slice_start_index_len_fail(self.start, slice.len());
}
// SAFETY: `self` is checked to be valid and in bounds above.
unsafe { &*self.get_unchecked(slice) }
}
fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
panic!("range start index {} out of range for slice of length {}", index, len);
}
它可以以不同的方式实现吗?我个人喜欢Python的实现方式。
v = [1, 2, 3, 4]
a = v[4] # -> Raises an exception - Similar to Rust's behavior (panic)
b = v[5] # -> Same, raises an exception - Also similar to Rust's
# (Equivalent to Rust's v[4..])
w = v[4:] # -> Returns an empty list - Similar to Rust's
x = v[5:] # -> Also returns an empty list - Different from Rust's, which panics
let idx = v.iter().position(|x| x == 5).unwrap_or(v.len()); let v = v[idx..];
。即使在空向量上,此代码也永远不会出现错误。否则,我们需要执行.unwrap_or(v.len() - 1)
,如果v
为空,则可能会出现错误。 - Filipe Rodrigues