Struct children shortcut (or variables shortcut)


#1

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);

#2

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 }

playground

This works because we either use name and age or we use person, but not both at the same time.


#3

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 }

#4

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.