Hi all
I am a new in rust but i wondering if there is a way to create shortcut (not variable) to struct children or to variable in general.
For example if i have Person struct with fields name and age, i can't hold the field contents if i not copy or clone them, i can't hold them as a ref variable in the same scope (multi borrow in the same scope error ). so my question is if there is a way like the example below to create shortcuts:
let person = Person{ name: "James".into(), age: 29};
person as {name, age};
// or
person as {name: my_name, age: my_age};
// or
person as person2;
println!("Hi i am {} {} yours old", name, age);
// you can still use in person here
println!("Hi i am {} {} yours old", person.name, person2.age);
No, as this would break the no-mutable-aliasing rule. You could temporarily decompose a struct into mutable references of it's fields like so.
fn main() {
let mut person = Person { name: "James".into(), age: 29 };
let Person { name, age } = &mut person;
println!("Hi i am {} {} yours old", name, age);
*name = "Bob".to_string();
println!("Hi i am {} {} yours old", person.name, person.age);
}
struct Person { name: String, age: u32 }
Thanks for your response. I have some notes i wrote them into the comments
fn main() {
let mut person = Person {
name: "James".into(),
age: 29,
};
{
// inmutable works
let Person { name, age } = person;
println!("Hi i am {} {} yours old", name, age);
}
{
let Person { name, age } = &mut person;
println!("Hi i am {} {} yours old", name, age);
*name = "Bob".to_string();
}
{
// you must to decompose all person fields, so what if there is a lot of filelds ?
let Person { name, _ } = &mut person;
println!("Hi i am {}", name);
*name = "Bob".to_string();
}
// this line works only in a separate scope if not i got the bellow error
// cannot borrow `person.age` as immutable because `person` is also borrowed as mutable
println!("Hi i am {} {} yours old", person.name, person.age);
}
struct Person { name: String, age: u32 }
You can use the .. expression in pattern matching like shown here.
I'll take your last code block as an example:
{
// you must to decompose all person fields, so what if there is a lot of filelds ?
let Person { name, _ } = &mut person;
println!("Hi i am {}", name);
*name = "Bob".to_string();
}
Here, name is actually &mut String (Or whatever you're .into()ing to), which makes the compiler groan about there being both a mutable reference and an immutable one to name, or in your second example, age as opposed to name. It shouldn't happen in code block #1 (At least I don't think so) because presumably there is a clone implementation for whatever you're .into()ing, and there definitely is a Clone implementation for usize, meaning that you just cloned the value, and didn't end up with a reference. I'd need a bit more information to infer that.