具有部分移动错误的结构

问题描述 投票:0回答:1

我有一个简单的结构及其两个实例,如下所示:

#[derive(Debug)]
struct User {
    first: String,
    last: String,
    age: u32,
}

let u1 = User {
    first: String::from("John"),
    last: String::from("Doe"),
    age: 22,
};

let u2 = User {
    first: String::from("Mary"),
    ..u1
};

println!("user: {:#?}", u1);

错误消息:

error[E0382]: borrow of moved value: `u1`
  --> src/main.rs:20:29
   |
15 |       let u2 = User {
   |  ______________-
16 | |         first: String::from("Mary"),
17 | |         ..u1
18 | |     };
   | |_____- value moved here
19 | 
20 |       println!("user: {:#?}", u1);
   |                               ^^ value borrowed here after partial move
   |
   = note: move occurs because `u1.last` has type `std::string::String`, which does not implement the `Copy` trait

我试图将其修改为..&u1,希望它能通过借入检查,以便我可以将基本结构(u1)扩展到u2,但无济于事,想知道我是否想在这里做些什么?

我理解这是因为u1.lastString,因此需要传递引用,但是我不确定如何在此情况下使其正常工作。

rust
1个回答
0
投票

您的User类型包含类型String,该类型拥有它拥有的字符串数据(并且不表示Copy),这就是为什么两个用户不能在内存中指向相同的名称。] >

您可能想要的解决方案:

#[derive(Debug, Clone)]
struct User {
    first: String,
    last: String,
    age: u32,
}

fn main() {
    let u1 = User {
        first: String::from("John"),
        last: String::from("Doe"),
        age: 22,
    };

    let u2 = User {
        first: String::from("Mary"),
        ..u1.clone() // Copy the strings into the new user 
        // (it also copies first, which is then thrown away? Maybe the compiler optimizes this away)
    };

    println!("user: {:#?}", u1);

}

但是如果您真的想让两个用户指向内存中的相同名称(肯定不会),有两个选择:

  • 您可以将String更改为&'static str。但是,这意味着在编译时必须指定它。 (您不能在运行时输入用户名并将其存储在用户中)

    #[derive(Debug)]
    struct User {
        first: &'static str,
        last: &'static str,
        age: u32,
    }
    
    fn main() {
        let u1 = User {
            first: "John",
            last: "Doe",
            age: 22,
        };
    
        let u2 = User {
            first: "Mary",
            ..u1
        };
    
        println!("user: {:#?}", u1);
    }
    
    
    • 您可以使用Rc来跟踪对内存的引用。这样,您不必担心一生以及谁拥有什么。 (尽管花费很少的运行时间)
    use std::rc::Rc;
    
    #[derive(Debug, Clone)]
    struct User {
        first: Rc<String>,
        last: Rc<String>,
        age: u32,
    }
    
    fn main() {
        let u1 = User {
            first: Rc::new(String::from("John")),
            last: Rc::new(String::from("Doe")),
            age: 22,
        };
    
        let u2 = User {
            first: Rc::new(String::from("Mary")),
            ..u1.clone() // Clone the references, not the actual string. For strings with just a couple characters, the time difference is completely negligible)
        };
    
        println!("user: {:#?}", u1);
    }
    
  • 如果以后要修改名称,并在u1和u2中都进行更改,请改用Rc<Mutex<String>>
© www.soinside.com 2019 - 2024. All rights reserved.