Почему index [] пытается переместить значение, но прямой вызов index не делает

Пример:

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])

Так что должно быть то же самое.

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При использовании квадратных скобок происходит скрытое разыменование. В документации по признаку индекса говорится:

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);
  |

Детская площадка

Кстати, почему *v.index(0) не компилируется без use std::ops::Index, а v[0] компилируется? Детская площадка

Some Name 25.05.2024 06:29

@SomeName По той же причине, по которой, например, std::ops::Add не обязательно должен находиться в области видимости, чтобы использовать оператор +. Язык определяет эти операторы для использования соответствующих свойств независимо от того, включили ли вы их в область видимости.

cdhowie 25.05.2024 11:12

@cdhowie Понятно, в любом случае поведение несколько сбивает с толку, по крайней мере, я не нашел этого в справочнике

Some Name 25.05.2024 11:55

Другие вопросы по теме