1

I want to make a function that receives a Vec and a position to change a number.

In JavaScript, this is really simple:

function replaceNumber(line, position, number) {
  return [
    ...line.slice(0, position),
    number,
    ...line.slice(position+1, line.length)
  ]
}

How can I make a similar function in Rust?

I tried this:

fn replace_number(line: Vec<i32>, point: i32, number: i32) -> Vec<i32> {
    return [
        &line[0..point as usize],
        &[number],
        &line[point as usize+1, point.len()]
    ].concat();
}

The result is an array of arrays. How can I make a destructuring like the JavaScript example?

Renato Cassino
  • 792
  • 1
  • 7
  • 27

1 Answers1

6

I want to make a function that receives a Vec and a position to change a number.

Rust has indexing syntax, just like JavaScript, so there's really no need for the destructuring.

fn replace_number(mut line: Vec<i32>, point: usize, number: i32) -> Vec<i32> {
    line[point] = number;
    line
}

or, more idiomatically:

fn replace_number(line: &mut Vec<i32>, point: usize, number: i32) {
    line[point] = number
}

Even more idiomatically would be to not have this function, probably, and just write it inline...

I want to know about immutably adding

With your original code, there's zero concern about anything "bad" happening because of mutability:

fn replace_number(line: Vec<i32>, point: i32, number: i32) -> Vec<i32>

This function takes ownership of the Vec, so the concept of immutability is rather moot here — the caller no longer has the Vec to care if it's mutated or not!

If you wanted to share data, you'd use a reference (a slice, specifically) like &[i32]. This is inherently immutable — you can't change it if you wanted to. You'd have to clone all the children and make the vector mutable:

fn replace_number(line: &[i32], point: usize, number: i32) -> Vec<i32> {
    let mut line = line.to_owned();
    line[point] = number;
    line
}

If you really wanted something like the JS syntax, you can use concat:

fn replace_number(line: &[i32], point: usize, number: i32) -> Vec<i32> {
    [&line[..point], &[number], &line[point + 1..]].concat()
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I want to know about immutability adding. I will change the function name. Is a good practice uses mutable variables in rust? I think that "is possible, but isnt good to use". I'm wrong? – Renato Cassino Aug 08 '18 at 14:04
  • 2
    @RenatoCassino that's not an easy question to answer. What are your reasons for avoiding mutability in JS? Do you know *why* mutability causes problems? Rust solves many (but not all) of those problems in different ways. – Shepmaster Aug 08 '18 at 14:11