1

I’m getting an error I’m not sure how to handle, related to a tuple assignment I’m trying. The incr function below gets a left-hand of expression not valid error. What am I misunderstanding?

struct Fib {
    i: u64,
    fa: u64,
    fb: u64,
}

impl Fib {
    fn incr(&mut self) {
        self.i += 1;
        (self.fa, self.fb) = (self.fa + self.fb, self.fa);
    }
}
Peter Varo
  • 11,726
  • 7
  • 55
  • 77
cryptograthor
  • 455
  • 1
  • 7
  • 19

1 Answers1

5

As the helpful error explanation says, you try to assign to a non-place expression. A place expression represents a memory location, and thus it can be a variable, a dereference, an indexing expression or a field reference, but a tuple is not one of these.

If you would use a binding, such as:

let (x, y) = (1, 2);

that would be a whole different story because let statements have different rules than assignment: the left hand side of a let statement is a pattern, not an expression, and (x, y) is a legal pattern.

To solve your problem, you may want to do the following and introduce a temporary variable, and then update the values of the members:

(The following is also fixing your fibonacci sequence, i.e. correcting the values of the members since they are naturally ordered as 'a' and 'b')

impl Fib {
    fn incr(&mut self) {
        self.i += 1;
        let fa = self.fa;
        self.fa = self.fb;
        self.fb += fa;
    }
}

Note: Albeit it was not your question, I would strongly advise to implement Iterator for your Fib type, in which case you wouldn't have to keep track of the index (i) because that would be available through the enumerate method. E.g.

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<Self::Item> {
        let fa = self.fa;
        self.fa = self.fb;
        self.fb += fa;
        Some(fa)
    }
}

And then you could use it as:

for (i, x) in my_fib.enumerate() { ... }

rustc --explain E0070

Peter Varo
  • 11,726
  • 7
  • 55
  • 77
  • 1
    Super clear, awesome explanation, and the recommendation about the Iterator trait is super useful! Thanks for that :) – cryptograthor Feb 17 '20 at 18:44
  • 1
    Also, thanks for suffering a Rust newbie, the links you provided gave me a sense of how I might approach similar situations to this in the future. – cryptograthor Feb 17 '20 at 18:57