i32; } struct AddCounter { a: i32, b: i32, } impl Cou-6ren">
gpt4 book ai didi

rust - 为什么在返回 "match arms have incompatible types"的函数中出现 `impl Trait` 错误?

转载 作者:行者123 更新时间:2023-11-29 07:57:21 37 4
gpt4 key购买 nike

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(...) 时出现错误:

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 表示法视为通用类型。你不能写:

fn get_counter<T>(a: i32, b: i32, op: &str) -> T {
match op {
"+" => AddCounter { a, b },
"*" => MulCounter { a, b },
_ => panic!(format!("{}{}", "未知的符号:", op)),
}
}

因为 AddCounterMulCounter 的类型不同:T 是什么?

您可以使用动态调度代替静态调度:

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)),
}
}

进一步说明

当您使用静态分派(dispatch)时,Rust 编译器单态化 代码:它为泛型类型的每个值生成一个新函数(更多详细信息请参见 What is monomorphisation with context to C++?)。这些返回值中的每一个都是“真正的”普通类型。在这种情况下,函数不能返回(例如)一个路径中的 String 和另一个路径中的 i32

dynamic dispatch的情况下,返回的不是“真实”类型,而是一个特征对象:编译器不知道真实类型;它只关心特征对象可以用作特征实现者。这就是您在这里需要的。

关于rust - 为什么在返回 "match arms have incompatible types"的函数中出现 `impl Trait` 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51543177/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com