Created
March 14, 2020 19:37
-
-
Save kohakus/727ec6237de80fff4c89661fd79ff665 to your computer and use it in GitHub Desktop.
Rust multiple immutable/mutable references
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Reference Rules for a variable | |
| // a). At any given time, you can have either (but not both of) one mutable reference or any number of immutable references. | |
| // b). References must always be valid. | |
| // First we define a simple struct | |
| struct Foo<T> { | |
| data: T, | |
| } | |
| impl<T> Foo<T> { | |
| fn new(data: T) -> Self { | |
| Foo { | |
| data, | |
| } | |
| } | |
| } | |
| // [Test1] | |
| // A variable cannot have its mutable reference and immutable reference at the same time. | |
| fn test1() { | |
| let mut foo = Foo::new("hello"); | |
| let _x = &mut foo; | |
| let _y = &foo; | |
| println!("{}", _x.data); | |
| println!("{}", _y.data); | |
| } | |
| // Test1 tells: | |
| // error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable. | |
| // [Test2] | |
| // We can use mutable and immutable references at the same time as long as they don't point to a same variable. | |
| fn test2() { | |
| let mut foo = Foo::new("hello"); | |
| let mut bar = Foo::new("world"); | |
| let _x = &mut foo; | |
| let _y = &bar; | |
| println!("{}", _x.data); | |
| println!("{}", _y.data); | |
| } | |
| // Test2 tells: | |
| // compiled successfully without error. | |
| // [Test3] | |
| // A variable can have its multiple immutable references at the same time. | |
| fn test3() { | |
| let mut foo = Foo::new("hello"); | |
| let _x = &foo; | |
| let _y = &foo; | |
| println!("{}", _x.data); | |
| println!("{}", _y.data); | |
| } | |
| // Test3 tells: | |
| // compiled successfully without error. | |
| // [Test4] | |
| // To prevent data conflict, a variable cannot have its multiple mutable references at the same time. | |
| fn test4() { | |
| let mut foo = Foo::new("hello"); | |
| let _x = &mut foo; | |
| let _y = &mut foo; | |
| println!("{}", _x.data); | |
| println!("{}", _y.data); | |
| } | |
| // Test4 tells: | |
| // error[E0499]: cannot borrow `foo` as mutable more than once at a time. | |
| // [Test5] | |
| // We can use multiple mutable references at the same time as long as they don't point to a same variable. | |
| fn test5() { | |
| let mut foo = Foo::new("hello"); | |
| let mut bar = Foo::new("world"); | |
| let _x = &mut foo; | |
| let _y = &mut bar; | |
| println!("{}", _x.data); | |
| println!("{}", _y.data); | |
| } | |
| // Test5 tells: | |
| // compiled successfully without error. | |
| // [Test6] (additional test) | |
| // We can just define unsafe references and get a passed compile, if we don't use them at all. | |
| // This may probably benefiting from non-lexical lifetimes. | |
| fn test6() { | |
| let mut foo = Foo::new("hello"); | |
| let _x = &mut foo; | |
| let _y = &mut foo; | |
| let _z = &foo; | |
| println!("{}", &foo.data); | |
| } | |
| // Test6 tells: | |
| // compiled successfully without error. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment