enums - Rust:将借来的结构传递给借来的枚举?
问题描述
我正在尝试将借来的结构传递给借来的枚举。
#[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);
}
}
}
编译给了我结果:
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
类型?我不想在这种情况下乱扔我的代码。
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());
}
}
}
解决方案
您错误地识别了问题,并且编译器在其错误注释上很准确。
您像这样定义了您的枚举:
pub enum Person {
Customer(CustomerData),
Employee(EmployeeData)
}
但是你决定你的枚举成员应该是Person::Customer(&CustomerData)
:
fn do_something_with_customer(customer: &CustomerData) {
let person = &Person::Customer(customer);
引用不可传递。因为&CustomerData
是引用并不意味着整个枚举都是对真实数据的引用(即&Person::Customer(CustomerData)
)。
有两种方法可以解决它;显而易见的是看是否CustomerData
实现Copy
。如果是这样,您可以取消引用(因此隐式复制):
fn do_something_with_customer(customer: &CustomerData) {
let person = Person::Customer(*customer);
(这是编译器建议的,所以我很确定你的类型实现了Copy
)
另一个选项是#[derive(Clone)]
在类型上并调用customer.clone()
. 同样,以额外分配为代价。
如果您真的想要枚举中的引用,则需要将枚举定义更改为:
pub enum Person<'a> {
Customer(&'a CustomerData),
Employee(&'a EmployeeData)
}
并处理对象属性现在是引用的事实,以及相关的所有问题。
推荐阅读
- ios - 条件绑定的初始化程序必须具有可选类型,而不是“URL”
- java - JOLT - 根据 if 条件在 JSONArray 中添加字段
- tfs - TFS 数据透视表?
- python - If, Else 在检查函数是否为真时不起作用
- python - 在 DF 中使用部分字符串
- javascript - 在 react-native 中创建了一个项目,但是当给 npx react-native run-android 一些错误时不断弹出
- visual-studio - 将 x86 项目转换为 x64 时如何解决错误 LNK1112?
- registry - 我可以在 Inno Setup 中一次注册多个 *.tlb 文件吗?
- excel - 文本框为数字时的自动过滤功能
- git - 如何在 GitLab 上指定要合并到的分支?