Как получить текущий элемент из итератора

Можно ли получить текущий элемент из итератора в Rust?

Мне бы хотелось иметь ту же функциональность, что и .next(), но она не будет переходить к следующему элементу, а просто вернет текущий элемент.

так:

fn main() {
    let x = vec![1, 2, 3, 4, 5];

    let iterator = x.iter(); // Create an iterator

    // y is now just a single i32 from the x array
    let y = iterator.next().unwrap();

    // I'm looking for method that will return the current item from the iterator
    // Something like iterator.current() which is not implemented for some reason.
    let z = iterator.current();
}
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете обернуть свой итератор в Peekable:

fn main() {
    let x = vec![1, 2, 3, 4, 5];

    let iterator = x.iter().peekable();

    let y = iterator.next().unwrap();

    let z = iterator.peek();
}

peek() возвращает предмет, который должен быть выдан, т. е. предмет, который будет возвращен в следующий раз, когда вы позвоните next(). Обратите внимание, что он возвращает ссылку, а не принадлежащий элемент.

Хм логично, спасибо! Есть ли причина, по которой нет такого метода, как iterator.current()?

Kuly14 20.11.2022 16:11

@ Kuly14 Kuly14 Не все итераторы могут предоставить его бесплатно. Например. они могут выполнять дорогостоящие вычисления для следующего элемента. Поэтому Rust предпочитает предоставлять тип, который сам может отслеживать это состояние. Я не думаю, что есть веская причина, почему, например. итераторы слайсов этого не делают, за исключением того, что «это обычно не требуется».

Chayim Friedman 20.11.2022 16:13

@ Kuly14 Моя ошибка: итераторы срезов делают. Они предоставляют методы as_slice(), которые возвращают все следующие элементы.

Chayim Friedman 20.11.2022 16:14

@ Kuly14, потому что для этого потребуется, чтобы каждый итератор сохранял элемент, что создает две сложности: дополнительное пространство для хранения чего-то, что обычно бесполезно, и либо конфликт с владением (если итератору необходимо сохранить последний полученный элемент), либо триггерная сторона- эффекты заранее (если они есть у итератора). peek делает шаг явным, поэтому потребитель итераторов точно знает, что он делает, и (надеюсь) не смешивает побочные эффекты и доступные для просмотра итераторы.

Masklinn 20.11.2022 20:09

Кроме того... его можно предоставить с помощью оболочки/адаптера, так зачем делать его частью базового контракта? То же самое с завершением: итератор должен остановиться, как только он будет возвращен None один раз, но это не гарантируется. Вместо этого можно использовать адаптер плавкого предохранителя для защелки, если это необходимо. Плюс технически может быть странное использование возобновляемых итераторов.

Masklinn 20.11.2022 20:09

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