Enums Rust:将借用的结构传递给借用的枚举?

Enums Rust:将借用的结构传递给借用的枚举?,enums,rust,borrow-checker,Enums,Rust,Borrow Checker,我正在尝试将借用的结构传递到借用的枚举中 #[派生(复制、克隆)] pub结构CustomerData{ //关于客户的许多领域 } #[衍生(复制、克隆)] 发布结构EmployeeData{ //关于员工的许多领域 } 酒吧枚举人{ 客户(CustomerData), 雇员(雇员数据) } fn与客户做某事(客户:&客户数据){ 让人=&人::顾客(顾客); //这可以工作,但这可能是一个大型结构。 //让person=&person::Customer(Customer.clone());

我正在尝试将借用的结构传递到借用的枚举中

#[派生(复制、克隆)]
pub结构CustomerData{
//关于客户的许多领域
}
#[衍生(复制、克隆)]
发布结构EmployeeData{
//关于员工的许多领域
}
酒吧枚举人{
客户(CustomerData),
雇员(雇员数据)
}
fn与客户做某事(客户:&客户数据){
让人=&人::顾客(顾客);
//这可以工作,但这可能是一个大型结构。
//让person=&person::Customer(Customer.clone());
一般方法(人);
}
fn与员工一起做事(员工:&EmployeeData){
让person=&person::Employee(Employee);
//这可以工作,但这可能是一个大型结构。
//让person=&person::Employee(Employee.clone());
一般方法(人);
}
fn一般方法(人:&人){
}
fn main(){
让person=person::Customer(CustomerData{});
比赛与个人{
人员::客户(数据)=>{
与客户(数据)合作;
}
人员::员工(数据)=>{
与员工(数据)合作;
}
}
}
我得到的结果是:

error[E0308]: mismatched types
  --> src/main.rs:19:36
   |
19 |     let person = &Person::Customer(customer);
   |                                    ^^^^^^^^
   |                                    |
   |                                    expected struct `CustomerData`, found reference
   |                                    help: consider dereferencing the borrow: `*customer`
   |
   = note: expected type `CustomerData`
              found type `&CustomerData`

error[E0308]: mismatched types
  --> src/main.rs:28:36
   |
28 |     let person = &Person::Employee(employee);
   |                                    ^^^^^^^^
   |                                    |
   |                                    expected struct `EmployeeData`, found reference
   |                                    help: consider dereferencing the borrow: `*employee`
   |
   = note: expected type `EmployeeData`
              found type `&EmployeeData`
我知道Rust编译器不允许我这样做,但考虑到我将结构传递给的枚举也是借用的,我觉得我应该能够这样做

此场景是否有模式/解决方法?可能使用
Rc
类型?在这种情况下,我不想把我的代码和它混在一起

使用std::rc::rc;
#[衍生(复制、克隆)]
pub结构CustomerData{
//关于客户的许多领域
}
#[衍生(复制、克隆)]
发布结构EmployeeData{
//关于员工的许多领域
}
酒吧枚举人{
客户(Rc),
雇员(Rc)
}
fn与客户合作(客户:Rc){
让人=&人::顾客(顾客);
//这可以工作,但这可能是一个大型结构。
//让person=&person::Customer(Customer.clone());
一般方法(人);
}
fn与员工一起做事(员工:Rc){
让person=&person::Employee(Employee);
//这可以工作,但这可能是一个大型结构。
//让person=&person::Employee(Employee.clone());
一般方法(人);
}
fn一般方法(人:&人){
}
fn main(){
让person=person::Customer(Rc::new(CustomerData{}));
比赛与个人{
人员::客户(数据)=>{
与客户(data.clone())做点什么;
}
人员::员工(数据)=>{
对员工(data.clone())做点什么;
}
}
}

您错误地识别了问题,编译器在错误注释中找到了正确的位置

您是这样定义枚举的:

pub enum Person {
    Customer(CustomerData),
    Employee(EmployeeData)
}
但随后您决定您的enum成员应该是
Person::Customer(&CustomerData)

引用是不可传递的。因为
&CustomerData
是一个引用,并不意味着整个枚举将是对真实数据的引用(即
&Person::Customer(CustomerData)

有两种方法可以解决这个问题;显而易见的是要看看
CustomerData
是否实现了
Copy
。如果是这样,您可以取消引用(因此隐式复制):

(这是编译器建议的,因此我非常确定您的类型实现了
Copy

另一个选项是对类型执行
#[派生(克隆)]
,然后调用
customer.Clone()
。同样,以额外分配为代价

如果确实希望在枚举中引用,则需要将枚举定义更改为:

pub enum Person<'a> {
    Customer(&'a CustomerData),
    Employee(&'a EmployeeData)
}

pub enum Person您错误地识别了问题,编译器在错误注释中找到了正确的位置

您是这样定义枚举的:

pub enum Person {
    Customer(CustomerData),
    Employee(EmployeeData)
}
但随后您决定您的enum成员应该是
Person::Customer(&CustomerData)

引用是不可传递的。因为
&CustomerData
是一个引用,并不意味着整个枚举将是对真实数据的引用(即
&Person::Customer(CustomerData)

有两种方法可以解决这个问题;显而易见的是要看看
CustomerData
是否实现了
Copy
。如果是这样,您可以取消引用(因此隐式复制):

(这是编译器建议的,因此我非常确定您的类型实现了
Copy

另一个选项是对类型执行
#[派生(克隆)]
,然后调用
customer.Clone()
。同样,以额外分配为代价

如果确实希望在枚举中引用,则需要将枚举定义更改为:

pub enum Person<'a> {
    Customer(&'a CustomerData),
    Employee(&'a EmployeeData)
}

pub enum person这个问题不是关于这个问题的安全性,而是关于以后可能发生的事情的安全性。如果复制结构(通过
Rc
Copy
Clone
),内存中实际上有两个独立的实体(
Rc
是一个特例),它们都是不可变的。如果你想改变这个数据呢?在
复制
克隆
的情况下,你可以这样做,但是你不会去碰其他的结构。在
Rc
的情况下,你不能,句号,然后你需要将这个
Rc
包装在
RefCell
周围,以获得内部的易变性。问题的关键在于你到底想要实现什么。您是否只需要数据的一个不可变副本,即使在拥有枚举的情况下也是如此<代码>钢筋混凝土
。您是否希望传递一个引用,并保证您的对象生存期限制合适<代码>&
。你的案子是真的吗<代码>复制/
克隆
很好。而且,没有真正的理由害怕引用。如果你以一种理智的方式编写代码,你只能在结构、特征和枚举的定义中看到它们的定义;在实际的业务逻辑中,大多数都被编译器省略和/或简化。真正的关键是有三种解决方案可以解决您的问题,它们都取决于您在代码片段之后对数据的处理方式