24

I wanted to create a vector with 'a'..'z' values (inclusive).

This doesn't compile:

let vec: Vec<char> = ('a'..'z'+1).collect();

What's the idiomatic way to have 'a'..'z'?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
bohdan_trotsenko
  • 5,167
  • 3
  • 43
  • 70

2 Answers2

37

Rust 1.26

As of Rust 1.26, you can use "inclusive ranges":

fn main() {
    for i in 0..=26 {
        println!("{}", i);
    }
}

Rust 1.0 through 1.25

You need to add one to your end value:

fn main() {
    for i in 0..(26 + 1) {
        println!("{}", i);
    }
}

This will not work if you need to include all the values:


However, you cannot iterate over a range of characters:

error[E0277]: the trait bound `char: std::iter::Step` is not satisfied
 --> src/main.rs:2:14
  |
2 |     for i in 'a'..='z'  {
  |              ^^^^^^^^^ the trait `std::iter::Step` is not implemented for `char`
  |
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::RangeInclusive<char>`

See Why can't a range of char be collected? for solutions.

I would just specify the set of characters you are interested in:

static ALPHABET: &str = "abcdefghijklmnopqrstuvwxyz";

for c in ALPHABET.chars() {
    println!("{}", c);
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Thanks! With the hint of yours I ended up with `let abc: Vec = (b'a'..b'z' + 1).map(|c| c as char).collect();` because there's not `std::iter::Step` – bohdan_trotsenko Apr 29 '17 at 17:29
  • More generally: `(start as u32..end as u32 + 1).flat_map(std::char::from_u32)`. – Veedrac May 01 '17 at 07:52
  • Why did they decide to make the end of the range exclusive? It feels very unintuitive... – obe Jul 12 '20 at 17:03
5

Inclusive range feature stabilised and released as part of version 1.26. Below is valid syntax for inclusive range

for i in 1..=3 {
    println!("i: {}", i);
}
tsatiz
  • 1,081
  • 7
  • 18