[英]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.