[英]How to Downcast a Supertrait to a SubTrait in Rust
I am currently trying to implement a trait from a library (in my case serde
), which expects a trait to be returned (see example function next
), but i only have a supertrait available, but i do not know how to downcast a supertrait to a subtrait.我目前正在尝试从库(在我的情况下
serde
)实现一个特征,它期望返回一个特征(参见示例 function next
),但我只有一个可用的超特征,但我不知道如何降低超特征为一个子特征。
Example Code:示例代码:
/// Imagine this type as a trait from a library, which i cannot change
trait SubTrait {
fn get_bool() -> bool;
}
trait SuperTrait: SubTrait {
fn get_string() -> String;
}
/// Imagine this type as a trait from a library, which i cannot change
trait GenericTrait {
fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
where
T: SubTrait;
}
struct SomeOtherStruct<'d, V: SuperTrait> {
field1: V,
_marker: std::marker::PhantomData<&'d ()>,
}
impl<'d, V> SomeOtherStruct<'d, V>
where
V: SuperTrait,
{
pub fn new(field: V) -> Self {
return Self {
field1: field,
_marker: std::marker::PhantomData,
};
}
pub fn do_something(self) -> Result<Option<V>, std::io::Error> {
return Ok(Some(self.field1));
}
}
struct ImplementingStruct<'d, V: SuperTrait> {
field1: V,
_marker: std::marker::PhantomData<&'d ()>,
}
/// Trying to implement the librarie's trait, while using a supertrait
impl<'d, V> GenericTrait for ImplementingStruct<'d, V>
where
// i have also already tried using "SuperTrait + SubTrait", but the same error happens
V: SuperTrait,
{
fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
where
T: SubTrait,
{
// Error: Expected "Option<T>" found "Option<V>"
return SomeOtherStruct::new(self.field1).do_something();
// TL;DR: how to cast "Option<V>" to "Option<T>"
}
}
rust version: 1.58.1 rust 版本:1.58.1
Notes:笔记:
SubTrait -> SuperTrait
, but this question is about SuperTrait -> SubTrait
)SubTrait -> SuperTrait
,但这个问题是关于SuperTrait -> SubTrait
)You cannot implement GenericTrait
this way.您不能以这种方式实现
GenericTrait
。
trait GenericTrait {
fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
where
T: SubTrait;
}
This trait means: For any type T
the caller asks for, if T: SubTrait
, next
will return a T
(wrapped in Result<Option...>
).这个特征意味着:对于调用者要求的任何类型
T
,如果T: SubTrait
, next
将返回一个T
(包装在Result<Option...>
中)。 So, if the caller asks for String
, next
returns a String
;因此,如果调用者要求
String
, next
返回一个String
; if the caller asks for i32
, next
returns an i32
;如果调用者要求
i32
, next
返回i32
; etc.等等
impl<'d, V> GenericTrait for ImplementingStruct<'d, V>
where
V: SuperTrait,
{
fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
where
T: SubTrait,
{
// Error: Expected "Option<T>" found "Option<V>"
return SomeOtherStruct::new(self.field1).do_something();
// TL;DR: how to cast "Option<V>" to "Option<T>"
}
}
This function body says: For any type T
the caller asks for, return V
instead.这个 function 正文说:对于调用者要求的任何类型
T
,请改为返回V
If the caller asks for String
, you would return V
.如果调用者要求
String
,您将返回V
。 If the caller asks for i32
, you would still return V
.如果调用者要求
i32
,您仍然会返回V
。
You have broken your promise to the compiler: you said in the function signature you'd return a T
, but you're returning a V
instead.您已将 promise 破坏给编译器:您在 function 签名中说您将返回
T
,但您返回的是V
。 This isn't possible and has nothing to do with supertraits or subtraits.这是不可能的,并且与超特征或子特征无关。 You can't write a function whose body and signature are in conflict.
您不能编写正文和签名冲突的 function。
In similar cases, sometimes it is appropriate to change the function signature.在类似情况下,有时更改 function 签名是合适的。 However, you can't change the function signature because that would make
impl GenericTrait for ImplementingStruct
untrue.但是,您不能更改 function 签名,因为这会使
impl GenericTrait for ImplementingStruct
不真实。 You can't implement a trait by not implementing the trait.你不能通过不实现特征来实现特征。
It is not clear what a solution might be in your case, but it is almost certainly unrelated to downcasting or supertraits.目前尚不清楚您的情况可能是什么解决方案,但几乎可以肯定它与向下转换或超特征无关。 The same error happens with only one trait .
只有一个 trait 会发生同样的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.