[英]How to Downcast a Supertrait to a SubTrait in Rust
我目前正在尝试从库(在我的情况下serde
)实现一个特征,它期望返回一个特征(参见示例 function next
),但我只有一个可用的超特征,但我不知道如何降低超特征为一个子特征。
示例代码:
/// 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 版本:1.58.1
笔记:
SubTrait -> SuperTrait
,但这个问题是关于SuperTrait -> SubTrait
)您不能以这种方式实现GenericTrait
。
trait GenericTrait {
fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
where
T: SubTrait;
}
这个特征意味着:对于调用者要求的任何类型T
,如果T: SubTrait
, next
将返回一个T
(包装在Result<Option...>
中)。 因此,如果调用者要求String
, next
返回一个String
; 如果调用者要求i32
, next
返回i32
; 等等
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>"
}
}
这个 function 正文说:对于调用者要求的任何类型T
,请改为返回V
如果调用者要求String
,您将返回V
。 如果调用者要求i32
,您仍然会返回V
。
您已将 promise 破坏给编译器:您在 function 签名中说您将返回T
,但您返回的是V
。 这是不可能的,并且与超特征或子特征无关。 您不能编写正文和签名冲突的 function。
在类似情况下,有时更改 function 签名是合适的。 但是,您不能更改 function 签名,因为这会使impl GenericTrait for ImplementingStruct
不真实。 你不能通过不实现特征来实现特征。
目前尚不清楚您的情况可能是什么解决方案,但几乎可以肯定它与向下转换或超特征无关。 只有一个 trait 会发生同样的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.