为什么我得到“匹配武器的类型不兼容"?返回“impl Trait"的函数中的错误? [英] Why do I get a "match arms have incompatible types" error in a function returning `impl Trait`?
问题描述
trait Counter {
fn count(&self) -> i32;
}
struct AddCounter {
a: i32,
b: i32,
}
impl Counter for AddCounter {
fn count(&self) -> i32 {
self.a + self.b
}
}
struct MulCounter {
a: i32,
b: i32,
}
impl Counter for MulCounter {
fn count(&self) -> i32 {
self.a * self.b
}
}
fn get_counter(a: i32, b: i32, op: &str) -> impl Counter {
match op {
"+" => AddCounter { a, b },
"*" => MulCounter { a, b },
_ => panic!(format!("{}{}", "未知的符号:", op)),
}
}
fn main() {}
当我调用 get_counter(...)
时出现错误:
I get an error when I call get_counter(...)
:
error[E0308]: match arms have incompatible types
--> src/main.rs:26:5
|
26 | / match op {
27 | | "+" => AddCounter { a, b },
28 | | "*" => MulCounter { a, b },
| | ------------------- match arm with an incompatible type
29 | | _ => panic!(format!("{}{}", "未知的符号:", op)),
30 | | }
| |_____^ expected struct `AddCounter`, found struct `MulCounter`
|
= note: expected type `AddCounter`
found type `MulCounter`
推荐答案
将 impl Trait
表示法视为泛型类型.你不能写:
See the impl Trait
notation as a generic type. You cannot write:
fn get_counter<T>(a: i32, b: i32, op: &str) -> T {
match op {
"+" => AddCounter { a, b },
"*" => MulCounter { a, b },
_ => panic!(format!("{}{}", "未知的符号:", op)),
}
}
因为AddCounter
和MulCounter
没有相同的类型:什么是T
?
because AddCounter
and MulCounter
do not have the same type: what is T
?
您可以使用动态分派代替静态分派:
You can use dynamic dispatch instead of static dispatch:
fn get_counter(a: i32, b: i32, op: &str) -> Box<dyn Counter> {
match op {
"+" => Box::new(AddCounter { a, b }),
"*" => Box::new(MulCounter { a, b }),
_ => panic!(format!("{}{}", "未知的符号:", op)),
}
}
进一步说明
当您使用静态分派时,Rust 编译器会单态代码:它为泛型类型的每个值生成一个新函数(参见 什么是带有上下文的单态化到 C++? 了解更多详细信息).每个返回值都是真正的"普通类型.在这种情况下,函数不能返回(例如)一个路径中的 String
和另一个路径中的 i32
.
Further explanation
When you use static dispatch, the Rust compiler monomorphizes the code: it generates a new function for each value of the generic type (see What is monomorphisation with context to C++? for more details). Each of those returned values are "real" plain types. In this case, a function cannot return (for example) a String
in one path and an i32
in another path.
对于 动态调度,返回的不是真实"类型而是trait对象:编译器不知道真实类型;它只关心 trait 对象是否可以用作 trait 实现者.这就是您所需要的.
In the case of dynamic dispatch, it is not the "real" type that is returned but a trait object: the compiler does not know the real type; it only cares that the trait object can be used as a trait implementor. That is what you need here.
这篇关于为什么我得到“匹配武器的类型不兼容"?返回“impl Trait"的函数中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!