How to destroy a tuple so that the bindings change?

If I have the following structure:

struct MyStruct { tuple: (i32, i32) }; 

And the following function:

 // This will not compile fn function(my_struct: &mut MyStruct) { let (val1, val2) = my_struct.tuple; val1 = 1; val2 = 2; } 

How do I take val1 and val2 as mutable, so when I reassign them, do the changes appear in the original structure?

+8
rust
source share
2 answers

You have a few problems:

  • You put &mut in the wrong place; &mut is part of the type, not an argument (unless you are destructing an argument that you are not).

  • You cannot call the struct argument because it is a keyword.

  • You cannot assign a mutable direct assignment link.

So, bearing in mind, the solution works here:

 #[derive(Debug)] struct MyStruct { tuple: (i32, i32), } fn function(s: &mut MyStruct) { let (ref mut val1, ref mut val2) = s.tuple; *val1 = 1; *val2 = 2; } fn main() { let mut s = MyStruct { tuple: (0, 0) }; function(&mut s); println!("{:?}", s); } 

The key here is that ref in the template binds by reference; combining with mut gives you a mutable link. In particular, he gives a pair of &mut i32 s. Since these links are links, you need to remove them in order to assign through them (otherwise you would try to re-assign the link).

+9
source share

You have two slightly different questions.

You can create mutable binding by saying mut twice:

 fn main() { let a = (1, 2); let (mut b, mut c) = a; b += 1; c += 2; println!("{}, {}", b, c); } 

But to change it in the original tuple, you will need a volatile link to this tuple:

 fn main() { let mut a = (1, 2); { let (ref mut b, ref mut c) = a; *b += 1; *c += 2; // Let mutable borrows end } println!("{:?}", a); } 
+8
source share

All Articles