繁体   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