Пример:
use std::ops::Index;
fn test(v: &Vec<Vec<i32>>) {
let t = v.index(0); //ok
let t = v[0]; //error, Vec<i32> does not implement Copy trait
}
Почему это происходит? Как указано в документации:
fn index(&self, index: I) -> &<Vec<T, A> as Index<I>>::Output
Выполняет операцию индексации (
container[index]
)
Так что должно быть то же самое.
При использовании квадратных скобок происходит скрытое разыменование. В документации по признаку индекса говорится:
container[index]
на самом деле является синтаксическим сахаром для*container.index(index)
Если вы добавите *
в первую строку, вы получите то же сообщение об ошибке:
error[E0507]: cannot move out of a shared reference
--> src/lib.rs:4:13
|
4 | let t = *v.index(0);
| ^^^^^^^^^^^ move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
|
help: consider removing the dereference here
|
4 - let t = *v.index(0);
4 + let t = v.index(0);
|
@SomeName По той же причине, по которой, например, std::ops::Add
не обязательно должен находиться в области видимости, чтобы использовать оператор +
. Язык определяет эти операторы для использования соответствующих свойств независимо от того, включили ли вы их в область видимости.
@cdhowie Понятно, в любом случае поведение несколько сбивает с толку, по крайней мере, я не нашел этого в справочнике
Кстати, почему
*v.index(0)
не компилируется безuse std::ops::Index
, аv[0]
компилируется? Детская площадка