18

How do I produce a list containing all the integers in Rust? I'm looking for the equivalent of Haskell's [n..m] or Python's range(n, m+1) but can't find anything.

I'm aware of the int::range function and thought it was what I was looking for, but it is made to iterate over a range, not to produce it.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Fabien
  • 12,486
  • 9
  • 44
  • 62
  • 1
    Be aware that because of Haskell's lazy evaluation, its list type in fact consists of an element and a function to continue producing the rest of the list (i.e., the next element and the *next* function, and so on), which means that in many ways Rust's `Iterator` types are in fact semantically a closer match for Haskell's `[a]` than `Vec` is. – glaebhoerl Jul 17 '16 at 10:43

4 Answers4

16

It is now possible to use ..= in Rust:

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

gives you a Vec from all the numbers from n to m.

..= is the inclusive range operator, whereas .. is exclusive.

antoyo
  • 11,097
  • 7
  • 51
  • 82
  • 7
    *to `m` inclusive* — pedantically, it's not truly inclusive. For example, there's no easy way to get all `u8` values from 0 to 255. There are various RFCs floating around that propose to add an inclusive range operator. – Shepmaster May 18 '16 at 22:14
  • 2
    This also can be write as `let vec = Vec::from_iter(n .. m + 1)`. – malbarbo May 18 '16 at 22:53
10

Note that this answer pertains to a pre-1.0 version of Rust and does not apply for 1.0. Specifically, Vec::from_fn was removed.

There's probably nothing really idiomatic as of now. There is a handful of convenience functions to construct vectors, for example you can use Vec::from_fn:

Vec::from_fn(m+1-n, |i| i+n)
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ben
  • 1,994
  • 12
  • 20
  • You'll find Counter a little more idiomatic. http://static.rust-lang.org/doc/std/iterator.html#struct-counter – dcolish Jun 28 '13 at 02:39
8

Note that this answer pertains to a pre-1.0 version of Rust and does not apply for 1.0. Specifically, std::iter::range and std::iter::range_inclusive were removed.

As of Rust 1.0.0-alpha, the easiest way to accomplish this is to use the convenience functions provided in the module std::iter: range and range_inclusive, which return iterators generating a list of numbers in the range [low, high) or [low, high], respectively.

In addition, you can build a vector from an iterator using the collect method:

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

Note that the return value of collect has its type explicitly specified in both its uses above. Normally, the Rust compiler can infer the types of expressions without an explicit specification, but collect is one of the most common cases for which the type cannot be fully inferred, in this case because it can't infer a concrete type that implements the trait FromIterator<A>, the return type of collect.

The type of a generic return value can be specified either as an explicit type in a let definition statement or inline by using the function::<Type>() syntax. Since inference fails only due to not knowing a concrete type implementing FromIterator<A>, it's possible, when explicitly specifying a generic type, to leave "holes" for type arguments which will be inferred, signified by _. This is done with the second call to collect above—in the expression Vec<_>, it's explicitly specified that the container receiving elements from collect is a Vec<T>, but the compiler figures out what exact type T must be. Currently, integers whose types are left unspecified and can't be inferred fall back to i32 (32-bit machine integer) as a default.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
telotortium
  • 3,383
  • 2
  • 23
  • 25
7

Since Rust 1.26.0 you can use the RangeToInclusive (..=) operator to generate an inclusive range.

let v: Vec<_> = (n..=m).collect()
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
belst
  • 2,285
  • 2
  • 20
  • 22