首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rust:将借用的结构传递给借用的枚举?

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

Stack Overflow用户
提问于 2019-09-08 18:20:31
回答 1查看 425关注 0票数 0

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

代码语言:javascript
复制
#[derive(Copy, Clone)]
pub struct CustomerData {
    // Many fields about customers
}

#[derive(Copy, Clone)]
pub struct EmployeeData {
    // Many fields about employees
}

pub enum Person {
    Customer(CustomerData),
    Employee(EmployeeData)
}

fn do_something_with_customer(customer: &CustomerData) {
    let person = &Person::Customer(customer);

    // This would work, but this can be a large struct.
    // let person = &Person::Customer(customer.clone());

    general_method(person);
}

fn do_something_with_employee(employee: &EmployeeData) {
    let person = &Person::Employee(employee);

    // This would work, but this can be a large struct.
    // let person = &Person::Employee(employee.clone());

    general_method(person);
}

fn general_method(person: &Person) {

}

fn main() {
    let person = Person::Customer(CustomerData { });

    match &person {
        Person::Customer(data) => {
            do_something_with_customer(data);
        }
        Person::Employee(data) => {
            do_something_with_employee(data);
        }
    }
}

编译后得到的结果是:

代码语言:javascript
复制
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类型?在这种情况下,我可不想把代码弄得乱七八糟。

代码语言:javascript
复制
use std::rc::Rc;

#[derive(Copy, Clone)]
pub struct CustomerData {
    // Many fields about customers
}

#[derive(Copy, Clone)]
pub struct EmployeeData {
    // Many fields about employees
}

pub enum Person {
    Customer(Rc<CustomerData>),
    Employee(Rc<EmployeeData>)
}

fn do_something_with_customer(customer: Rc<CustomerData>) {
    let person = &Person::Customer(customer);

    // This would work, but this can be a large struct.
    // let person = &Person::Customer(customer.clone());

    general_method(person);
}

fn do_something_with_employee(employee: Rc<EmployeeData>) {
    let person = &Person::Employee(employee);

    // This would work, but this can be a large struct.
    // let person = &Person::Employee(employee.clone());

    general_method(person);
}

fn general_method(person: &Person) {

}

fn main() {
    let person = Person::Customer(Rc::new(CustomerData { }));

    match &person {
        Person::Customer(data) => {
            do_something_with_customer(data.clone());
        }
        Person::Employee(data) => {
            do_something_with_employee(data.clone());
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-08 18:30:36

您错误地识别了这个问题,编译器在其错误注释中说得很对。

您定义枚举的方式如下:

代码语言:javascript
复制
pub enum Person {
    Customer(CustomerData),
    Employee(EmployeeData)
}

但是您决定您的枚举成员应该是Person::Customer(&CustomerData)

代码语言:javascript
复制
fn do_something_with_customer(customer: &CustomerData) {
    let person = &Person::Customer(customer);

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

有两种方法可以修复它;最明显的方法是查看CustomerData是否实现了Copy。如果是这样的话,你可以直接取消引用(并隐式复制):

代码语言:javascript
复制
fn do_something_with_customer(customer: &CustomerData) {
    let person = Person::Customer(*customer);

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

另一种选择是对类型执行#[derive(Clone)]并调用customer.clone()。再一次,以额外的分配为代价。

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

代码语言:javascript
复制
pub enum Person<'a> {
    Customer(&'a CustomerData),
    Employee(&'a EmployeeData)
}

并处理对象属性现在是一个引用的事实,以及所有相关的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57841038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档