简体   繁体   English

如何在 Rust 中将超特征向下转换为子特征

[英]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:笔记:

  • i know This Rust Issue exists, but i dont think it is related (it is about SubTrait -> SuperTrait , but this question is about SuperTrait -> SubTrait )我知道这个 Rust 问题存在,但我不认为它是相关的(它是关于SubTrait -> SuperTrait ,但这个问题是关于SuperTrait -> SubTrait
  • from what i can tell, Boxing is not a option here据我所知,拳击不是这里的选择

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: SubTraitnext将返回一个T (包装在Result<Option...>中)。 So, if the caller asks for String , next returns a String ;因此,如果调用者要求Stringnext返回一个String if the caller asks for i32 , next returns an i32 ;如果调用者要求i32next返回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 会发生同样的错误

Similar Questions类似问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM