Подтвердить что ты не робот

В Rust, каков идиоматический эквивалент Haskell [n..m]?

Как создать список, содержащий все целые числа в Rust? Я ищу эквивалент Haskell [n..m] или Python range(n, m+1), но ничего не могу найти.

Я знаю о функции int::range и думал, что это то, что я искал, но он сделан для итерации по диапазону, а не для его создания.

4b9b3361

Ответ 1

Обратите внимание, что этот ответ относится к версии ржавчины до версии 1.0 и не относится к 1.0. В частности, были удалены std::iter::range и std::iter::range_inclusive.

В отличие от Rust 1.0.0-alpha, самый простой способ добиться этого - использовать функции удобства, предусмотренные в модуле std::iter: range и range_inclusive, которые возвращают итераторы генерируя список чисел в диапазоне [низкий, высокий) или [низкий, высокий], соответственно.

Кроме того, вы можете построить вектор из итератора с помощью метода collect:

use std::iter::range_inclusive;
let first_hundred: Vec<i32> = range_inclusive(1, 100).collect();
println!("upper bound inclusive: {:?}, exclusive: {:?}",
         first_hundred,
         range(101, 201).collect::<Vec<_>>());

Обратите внимание, что возвращаемое значение collect имеет свой тип, явно указанный в обоих его применениях выше. Обычно компилятор Rust может выводить типы выражений без явной спецификации, но collect является одним из наиболее распространенных случаев, для которых тип не может быть полностью выведен, в этом случае, поскольку он не может вывести конкретный тип, который реализует признак FromIterator<A>, возвращаемый тип collect.

Тип общего возвращаемого значения может быть указан либо как явный тип в операторе определения let, либо в строке с использованием синтаксиса function::<Type>(). Поскольку вывод не выполняется только из-за незнания конкретного типа реализации FromIterator<A>, при явном указании родового типа можно оставить "дыры" для аргументов типа, которые будут выведены, обозначенные _. Это делается при втором вызове collect выше — в выражении Vec<_> он явно указал, что принимающие элементы контейнера из collect являются Vec<T>, но компилятор определяет, какой именно тип T должен быть. В настоящее время целые числа, типы которых остаются неопределенными и не могут быть выведены, возвращаются к i32 (32-разрядное целое число) по умолчанию.

Ответ 2

Теперь можно использовать .. в Rust:

let vec: Vec<_> = (n .. m + 1).collect();

дает Vec от всех чисел от n до m.

Как отмечено в комментарии Shepmaster, будьте осторожны, это не сработает, если вам нужен диапазон до максимального значения типа (255 для u8).

Ответ 3

Обратите внимание, что этот ответ относится к версии ржавчины до версии 1.0 и не относится к 1.0. В частности, Vec::from_fn был удален.

На данный момент, вероятно, нет ничего действительно идиоматического. Существует несколько удобных функций для построения векторов, например, вы можете использовать Vec::from_fn:

Vec::from_fn(m+1-n, |i| i+n)

Ответ 4

Начиная с Rust 1.26.0 вы можете использовать RangeToInclusive (..=) для генерации включающего диапазона.

let v: Vec<_> = (n..=m).collect()