Why does variable `n` need initialized?

I tested this code and I have to initialise m that I renamed n in the second line of function.

Here is what I have :

fn main() {
println!("Hello, world!");
let m: String = String::from("Hello world");
let mut x: usize = ret_s(&m);

let slice = &m[..x];
println!("slice ======  {}", slice);

}

fn ret_s(x: &str) -> usize {
let m = x.as_bytes();
let mut n: usize = 4;
for (i, &item) in m.iter().enumerate() {
if item == b' ' {
n = i;
}
}

return n;

}

And the slice returned is Hello, why should n be initialised ?
I'm new to Rust.

Probably not the most needed note, but:

  1. Avoid mutation;
  2. Use .bytes() instead of .as_bytes().iter().

Something like this:

fn ret_s(x: &str) -> usize {
    x.bytes()
      .enumerate()
      .filter_map(|(n, byte)| if byte == 32 {Some(n)} else {None}
      .nth(0)
      .unwrap()
}

if you need the number of the first b' ' in x.

P.S. If someone knows how to do this in a better way using iterators, please tell me :wink:

1 Like
  • .nth(0) is simply next()
  • .filter_map(…).next() is simply .find_map(…)
  • .enumerate().find_map() is just .position()
4 Likes

Because the loop does not initialize n if x is empty (the loop never runs) or does not contain any spaces (the if body never runs). Rust insists that you think about every possible scenario, not just the "happy path" or some easy example input. What should ret_s("") or ret_s("hello") return?

The canonical answer is that rather than usize it should return Option<usize> and indeed that’s what the appropriate standard iterator method does:

x.bytes().position(|&byte| byte == b' ')

is equivalent to your loop, except it returns Some(usize) or None if x does not contain a space.

6 Likes