Return 结果<Box<dyn Trait>> 在一场比赛中
Return Result<Box<dyn Trait>> in a match
我有一组实现给定特征的类型,我想从字符串名称中获取具体类型对象,奇怪的是,当我的 match
returns Box<dyn Trait>
但是当我将它包装在 Result
.
中时却没有
鉴于此特征和类型:
trait Shape {
fn edges(&self) -> u8;
}
struct Triangle {}
impl Shape for Triangle {
fn edges(&self) -> u8 {
3
}
}
struct Rectangle {}
impl Shape for Rectangle {
fn edges(&self) -> u8 {
4
}
}
这个有效:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Box::new(Triangle {}),
"rectangle" => Box::new(Rectangle {}),
_ => panic!("Bad value"),
};
Ok(shape.edges())
}
然而这不是:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Ok(Box::new(Triangle {})),
"rectanble" => Ok(Box::new(Rectangle {})),
_ => Err("bad value")
}?;
Ok(shape.edges())
}
错误:
error[E0308]: `match` arms have incompatible types
--> src/main.rs:24:24
|
22 | let shape: Box<dyn Shape> = match name {
| _________________________________-
23 | | "triangle" => Ok(Box::new(Triangle {})),
| | ------------------------- this is found to be of type `Result<Box<Triangle>, _>`
24 | | "rectanble" => Ok(Box::new(Rectangle {})),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Triangle`, found struct `Rectangle`
25 | | _ => Err("bad value")
26 | | }?;
| |_____- `match` arms have incompatible types
|
= note: expected type `Result<Box<Triangle>, _>`
found enum `Result<Box<Rectangle>, _>`
当然这只是一个例子,在我的代码中我想使用后一种情况来处理错误。
为什么后一种情况不起作用?
您需要将 Box
转换为 Box<dyn Shape>
,否则编译器不够智能(仍然)无法忽略类型:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Ok(Box::new(Triangle {}) as Box<dyn Shape>),
"rectanble" => Ok(Box::new(Rectangle {}) as Box<dyn Shape>),
_ => Err("bad value")
}?;
Ok(shape.edges())
}
顺便说一句,因为您已经在构建结果,所以您可以将 edges
映射到原始构建的结果:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape = match name {
"triangle" => Ok(Box::new(Triangle {}) as Box<dyn Shape>),
"rectanble" => Ok(Box::new(Rectangle {}) as Box<dyn Shape>),
_ => Err("bad value")
};
shape.map(|s| s.edges())
}
我有一组实现给定特征的类型,我想从字符串名称中获取具体类型对象,奇怪的是,当我的 match
returns Box<dyn Trait>
但是当我将它包装在 Result
.
鉴于此特征和类型:
trait Shape {
fn edges(&self) -> u8;
}
struct Triangle {}
impl Shape for Triangle {
fn edges(&self) -> u8 {
3
}
}
struct Rectangle {}
impl Shape for Rectangle {
fn edges(&self) -> u8 {
4
}
}
这个有效:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Box::new(Triangle {}),
"rectangle" => Box::new(Rectangle {}),
_ => panic!("Bad value"),
};
Ok(shape.edges())
}
然而这不是:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Ok(Box::new(Triangle {})),
"rectanble" => Ok(Box::new(Rectangle {})),
_ => Err("bad value")
}?;
Ok(shape.edges())
}
错误:
error[E0308]: `match` arms have incompatible types
--> src/main.rs:24:24
|
22 | let shape: Box<dyn Shape> = match name {
| _________________________________-
23 | | "triangle" => Ok(Box::new(Triangle {})),
| | ------------------------- this is found to be of type `Result<Box<Triangle>, _>`
24 | | "rectanble" => Ok(Box::new(Rectangle {})),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Triangle`, found struct `Rectangle`
25 | | _ => Err("bad value")
26 | | }?;
| |_____- `match` arms have incompatible types
|
= note: expected type `Result<Box<Triangle>, _>`
found enum `Result<Box<Rectangle>, _>`
当然这只是一个例子,在我的代码中我想使用后一种情况来处理错误。
为什么后一种情况不起作用?
您需要将 Box
转换为 Box<dyn Shape>
,否则编译器不够智能(仍然)无法忽略类型:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape: Box<dyn Shape> = match name {
"triangle" => Ok(Box::new(Triangle {}) as Box<dyn Shape>),
"rectanble" => Ok(Box::new(Rectangle {}) as Box<dyn Shape>),
_ => Err("bad value")
}?;
Ok(shape.edges())
}
顺便说一句,因为您已经在构建结果,所以您可以将 edges
映射到原始构建的结果:
fn get_shape_edges(name: &str) -> Result<u8, &str> {
let shape = match name {
"triangle" => Ok(Box::new(Triangle {}) as Box<dyn Shape>),
"rectanble" => Ok(Box::new(Rectangle {}) as Box<dyn Shape>),
_ => Err("bad value")
};
shape.map(|s| s.edges())
}