Не соответствие ожидаемому типу
#![feature(type_alias_impl_trait)]
#![feature(return_position_impl_trait_in_trait)]
fn main() {
let payment = PaymentHelper::get_payment_factory(PaymentType::Sber).create_payment();
payment.pay(Order::from("November 2022 23:44".to_owned(), 57, "John".to_owned()));
}
struct Order{
time: String,
amount: i32,
name: String,
}
impl Order{
fn from(time: String, amount: i32, name: String) -> Self {
Self{time: time, amount: amount, name: name}
}
}
enum PaymentType{
Sber,
Vtb
}
trait PaymentFactoryInterface{
fn create_payment(&self) -> impl PaymentInterface;
}
trait PaymentInterface{
fn pay(&self, order: Order);
}
struct SberBank;
struct SberBankFactory;
impl PaymentInterface for SberBank {
fn pay(&self, order: Order) {
println!("Sber pay success. {} dollars was transfered at {} by {}", order.amount, order.time, order.name);
}
}
impl PaymentFactoryInterface for SberBankFactory{
fn create_payment(&self) -> impl PaymentInterface {
SberBank{}
}
}
struct VtbBank;
struct VtbBankFactory;
impl PaymentInterface for VtbBank {
fn pay(&self, order: Order) {
println!("VTB pay success. {} dollars was transfered at {} by {}", order.amount, order.time, order.name);
}
}
impl PaymentFactoryInterface for VtbBankFactory{
fn create_payment(&self) -> impl PaymentInterface {
VtbBank{}
}
}
struct PaymentHelper;
impl PaymentHelper {
fn get_payment_factory(payment_type: PaymentType) -> impl PaymentFactoryInterface {
match payment_type {
PaymentType::Vtb => {VtbBankFactory{}}
PaymentType::Sber => {SberBankFactory{}}
// _ => {None}
}
}
}
Выход:
error[E0308]: `match` arms have incompatible types
--> src/main.rs:70:35
|
68 | / match payment_type {
69 | | PaymentType::Vtb => {VtbBankFactory{}}
| | ---------------- this is found to be of type `VtbBankFactory`
70 | | PaymentType::Sber => {SberBankFactory{}}
| | ^^^^^^^^^^^^^^^^^ expected `VtbBankFactory`, found `SberBankFactory`
71 | | // _ => {None}
72 | | }
| |_________- `match` arms have incompatible types
|
help: you could change the return type to be a boxed trait object
|
67 | fn get_payment_factory(payment_type: PaymentType) -> Box<dyn PaymentFactoryInterface> {
| ~~~~~~~ +
help: if you change the return type to expect trait objects, box the returned expressions
|
69 ~ PaymentType::Vtb => {Box::new(VtbBankFactory{})}
70 ~ PaymentType::Sber => {Box::new(SberBankFactory{})}
Как я могу это исправить?
P.S если использовать предложенное исправление то
error[E0038]: the trait `PaymentFactoryInterface` cannot be made into an object
--> src/main.rs:67:62
|
67 | fn get_payment_factory(payment_type: PaymentType) -> Box<dyn PaymentFactoryInterface> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `PaymentFactoryInterface` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src/main.rs:28:33
|
27 | trait PaymentFactoryInterface{
| ----------------------- this trait cannot be made into an object...
28 | fn create_payment(&self) -> impl PaymentInterface;
| ^^^^^^^^^^^^^^^^^^^^^ ...because method `create_payment` references an `impl Trait` type in its return type
= help: consider moving `create_payment` to another trait
Источник: Stack Overflow на русском