- 有
S1
和S2
分别实现了ATrait
特性
trait ATrait {}
struct S1 {}
impl ATrait for S1 {}
struct S2 {}
impl ATrait for S2 {}
- 以下代码是能够编译通过的,返回一个
Result
fn foo1(i: i32) -> Result<Box<ATrait>, ()> {
if i < 0 {
Ok(Box::new(S1 {}))
} else {
Ok(Box::new(S2 {}))
}
}
- 但是以下代码就无法编译通过(实际上就是上面的
foo1
方法的返回值通过另一个函数返回)
fn f1() -> Result<Box<S1>, ()> {
Ok(Box::new(S1 {}))
}
fn f2() -> Result<Box<S2>, ()> {
Ok(Box::new(S2 {}))
}
fn foo2(i: i32) -> Result<Box<ATrait>, ()> {
if i < 0 {
f1()
} else {
f2()
}
}
- 报错内容如下,是因为
f1
返回值的类型与foo2
不匹配导致
46 | fn foo2(i: i32) -> Result<Box<ATrait>, ()> {
| ----------------------- expected `std::result::Result<std::boxed::Box<(dyn ATrait + 'static)>, ()>` because of return type
47 | if i < 0 {
48 | f1()
| ^^^^ expected trait ATrait, found struct `S1`
|
= note: expected type `std::result::Result<std::boxed::Box<(dyn ATrait + 'static)>, _>`
found type `std::result::Result<std::boxed::Box<S1>, _>`
- 但是如果返回的不是
Result
,而是ATrait
对象指针,则编译是能通过的
fn foo3(i: i32) -> Box<ATrait> {
if i < 0 {
f1().unwrap()
} else {
f2().unwrap()
}
}
问题
- 为什么
foo3
(返回Box的函数)就不存在类型不匹配的问题? - 这种情况,有没有比较好的实现方式?(不需要在
foo2
方法中把f1
和f2
函数返回的结果转换的那种)还是说只能在foo2
中把f1
和f2
的Result
拆开再重新包装?
丢给我几个链接或者关键词也可以的,感谢社区各位大佬!
1
共 2 条评论, 1 页
评论区
写评论原来是因为
Result
没有隐式转换机制,谢谢! 对以下内容的回复:Box<S1>
到Box<dyn ATrait>
的转换可以是隐式的。 但是Result
和普通的Enum和Struct是一样的,类型之间没有这种转换,只能显式做