使用不同的实现返回性状实现
以下实现似乎很简单。由于某种原因,我不明白问题是什么。编译器不编译。
这里的主要问题是我无法更改函数 test(bool)
的声明,因为它不在框架之外。
/// Implemented in a 3rd party framework:
trait Share {
fn dosomething();
}
impl Share for String {
fn dosomething() {
todo!()
}
}
/// My part of the implementation:
// this function `test` will be handed over (as a function) to a framework method, which I can't change it's return type.
fn test(data: bool) -> Result<impl Share, String> {
return if data {
Ok(Data {})
} else {
Ok("a string".to_string())
}
}
struct Data {
}
impl Share for Data {
fn dosomething() {
todo!()
}
}
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:5:12
|
5 | Ok("a string".to_string())
| ^^^^^^^^^^^^^^^^^^^^^^ expected struct `Data`, found struct `String`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于
的两个分支如果
-else
表达式必须评估相同类型的值。但是,在您的代码中:第一个分支评估
ok(data {})
,因此将其类型推断为result&lt; data,string&gt;
,而第二个分支评估为ok(“ a String” .to_string())
,并将其推断为result&lt; string,string&gt;
。由于这些类型是不同的,因此会导致编译时间误差。如果
共享
是,例如:然后,由于值
data {}
和“ a String” .TO_STRING()
实现 share ,您通过将它们放在box&lt; dyn共享&gt;
中,可以将它们变成特征对象。这样,您仍然可以通过依靠动态多态性来实现(运行时间 x )类型擦除:请注意,此处两个分支值都是相同类型的:
result&lt; box&lt; dyn&lt; dyn&lt; dyn&gt&gt ;,字符串&gt;
因为类型box&lt; share&gt;
andbox&lt; string&gt;
在运行时删除 > box&lt; dyn共享&gt; 。x 您的目标是使用您的初始
Impl share
瞄准编译时类型的擦除。The problem is that both branches of the
if
-else
expression must evaluate to a value of the same type. However, in your code:The first branch evaluates to
Ok(Data {})
, and therefore its type would be inferred asResult<Data, String>
, whereas the second branch evaluates toOk("a string".to_string())
and it would be inferred asResult<String, String>
. Since these types are different, it results in a compile-time error.If
Share
were an object-safe trait, e.g.:Then, since the values
Data{}
and"a string".to_string()
implementShare
, you could turn them into trait objects by placing them into aBox<dyn Share>
. This way, you would still achieve a (run-timeX) type erasure by relying on dynamic polymorphism:Note that here both branch values are of the same type:
Result<Box<dyn Share>, String>
because the typesBox<Share>
andBox<String>
are erased at run-time toBox<dyn Share>
.XYou were aiming at a compile-time type erasure with your initial
impl Share
.如果您确实需要为结果的
OK
变体提供不同的类型,则所有这些类型都实现share
,则必须切换到动态多态性。这意味着堆分配(
box
),因为该值是在函数内部产生的(您无法返回对本地的引用)。但是,如果您只想提供实施
共享
的有限类型,则可以返回enum
而不是Impl Inld share
。If you really need to provide different types for the
Ok
variant of the result, all of them implementingShare
, then you have to switch to dynamic polymorphism.This implies heap allocation (
Box
) because the value is produced inside the function (you cannot return a reference to a local).However, if you only want to provide a limited set of types implementing
Share
then, you can return anenum
instead ofimpl Share
.