簡體   English   中英

如何在 Rust 中將超特征向下轉換為子特征

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

筆記:

  • 我知道這個 Rust 問題存在,但我不認為它是相關的(它是關於SubTrait -> SuperTrait ,但這個問題是關於SuperTrait -> SubTrait
  • 據我所知,拳擊不是這里的選擇

您不能以這種方式實現GenericTrait

trait GenericTrait {
    fn next<T>(&mut self) -> Result<Option<T>, std::io::Error>
    where
        T: SubTrait;
}

這個特征意味着:對於調用者要求的任何類型T ,如果T: SubTraitnext將返回一個T (包裝在Result<Option...>中)。 因此,如果調用者要求Stringnext返回一個String 如果調用者要求i32next返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM