这个错误是什么意思?
error[E0308]: mismatched types
--> src/main.rs:50:35
|
50 | PaymentType::InvoiceIn => InvoiceIn {
| ___________________________________^
51 | | name: "Invoice 1".to_string(),
52 | | payed: false,
53 | | },
| |_________^ expected `dyn Payable`, found `InvoiceIn`
|
= note: expected trait object `dyn Payable`
found struct `InvoiceIn`
= help: `InvoiceIn` implements `Payable` so you could box the found value and coerce it to the trait object `Box<dyn Payable>`, you will have to change the expected type as well
For more information about this error, try `rustc --explain E0308`.
代码:
trait Payable {
fn toggle_payed(&mut self);
}
enum PaymentType {
InvoiceOut,
InvoiceIn,
}
struct Payment {
r#type: PaymentType,
}
struct InvoiceOut {
name: String,
payed: bool,
}
impl Payable for InvoiceOut {
fn toggle_payed(&mut self) {
self.payed = !self.payed
}
}
struct InvoiceIn {
name: String,
payed: bool,
}
impl Payable for InvoiceIn {
fn toggle_payed(&mut self) {
self.payed = !self.payed
}
}
fn save_invoice_in(invoice: &InvoiceIn) {
println!("{}", invoice.name)
}
fn save_invoice_out(invoice: &InvoiceOut) {
println!("{}", invoice.name)
}
fn main() {
let payment = Payment {
r#type: PaymentType::InvoiceOut, // This comes from user!
};
let payable: dyn Payable = match payment.r#type {
PaymentType::InvoiceIn => InvoiceIn {
name: "Invoice 1".to_string(),
payed: false,
},
PaymentType::InvoiceOut => InvoiceOut {
name: "Invoice 2".to_string(),
payed: false,
},
};
// Do something else with payable here
payable.toggle_payed();
// Do something else with payable here
match payment.r#type {
PaymentType::InvoiceIn => save_invoice_in(&payable),
PaymentType::InvoiceOut => save_invoice_out(&payable),
};
}
这里尝试展示评论中提到的两种可能性。
此示例细分为三个部分:
std::any::Any
以便向下转换为原始类型,enum
.理论上,“动态”解决方案可以比“公共”部分中存在的变体开放更多的变体(在其他地方实现),但由于您似乎需要某种向下转型,所以我认为它并不真正适合您的需要。
在我看来,“枚举”解决方案是最好的,尤其是因为你似乎需要向下转换到有限数量的变体(在枚举中一次全部知道)。请注意,crate
enum_dispatch
可以帮助通过变体转发方法调用。