Increase integer as side effect?


#1

Is it possible to have a function that increases an integer as a side effect? I am looking for the following behaviour:

fn main() {
    let mut i:usize = 1;
    succ(&mut i);
    assert_eq!(i,2);
}

fn succ(i:&mut usize) {
    // increase i by 1
}

I tried a couple of things, but the borrow checker (rightfully) complains about my attempts so far.


#2

*i += 1;


#3

Yay thanks!


#4

Can *i += 1 be rewritten in less terse way? Is it syntactic sugar for something? For instance how would I replace i by myop(i)`?


#5

Not sure you can strip more from it, but breaking the parts down may help you:

  • *i gives you the variable the reference points towards, so it’s like an &mut i -> i conversion.
  • Rust doesn’t have the x++ operator, so x += 1 is probably as far as you can go. It’s basically sugar (although counts as a different operator) for x = x + 1, so if you can modify that expression, you can do anything.

I guess I had higher ambitions when I started the answer, but the *i turning &mut i into i is the main take away. And with numbers you can also do that to “unpack” it, since it will be copied automatically. A non-Copy type would not allow the same amount of freedom.


#6
*i = *i + 1
*i = myop(*i)

#7

Thanks all! Now its much clearer for me whats going on!


#8

I just realized that you said less terse and not more terse. :roll_eyes: I guess I managed to give a hint anyway.


#9

Yeah :smiley: I wondered about the strip at the start of your answer, but otherwise your answer was what I was looking for :smiley:


#10

Let me check if I understand things correctly now:

If *i appears on the left like *i = foo it means variable i now owns foo. Is that correct?

An *i on the right hand side like foo = *i is only allowed, if i implements Copy. It then simply copies the content of i to foo.


#11

Yes, that’s correct. However, there’s one additional case. The * operator is also used to move a value out of a Box, which does not need to be Copy.

let s: Box<String> = foo(); let s: String = *s;

String is not Copy, but the * extracts the contents of the Box.