【问题标题】:Rust: Shorten generic type boundsRust:缩短泛型类型界限
【发布时间】:2020-04-30 20:37:03
【问题描述】:

有没有办法缩短 rust 中的泛型类型边界? 这是我必须放在很多结构 impls 等上的混乱:

pub struct IncomingClientMessageWithAddress<State, Msg>
    where State: AppState + Clone + serde::Serialize + serde::de::DeserializeOwned + std::marker::Unpin + 'static,
          Msg: AppEvent + Clone + serde::Serialize + serde::de::DeserializeOwned + std::marker::Unpin + 'static {
...

我基本上想做这样的事情(我知道下面不适用于特质):

type MyStateAlias = AppState + Clone + serde::Serialize + serde::de::DeserializeOwned + std::marker::Unpin + 'static;
type MyEventAlias = AppEvent + Clone + serde::Serialize + serde::de::DeserializeOwned + std::marker::Unpin + 'static;


pub struct IncomingClientMessageWithAddress<State, Msg>
    where State: MyStateAlias,
          Msg: MyEventAlias {
...

【问题讨论】:

标签: generics rust


【解决方案1】:

我有时意识到某个特征的所有出现都与其他特征相关联。在您的情况下,如果 AppState alwaysCloneSerialize 一起出现,您可能已经在状态之上需要这些:

trait AppState : Clone + Serialize {/*...*/}

如果没有,你仍然可以定义一个辅助特征

trait AuxAppState: AppState + Clone + Serialize {/*...*/}

并且需要State : AuxAppState

然后,要自动派生AuxAppState,您必须为implements StateCloneSerialize 的每种类型都使用impl

impl<T> AuxAppState for T where T: AppState + Clone + Serialize {}

最后,定义和implmenting AuxAppState 可能由macro to save some keystrokes 完成:

macro_rules! auxiliary_trait{
    ($traitname: ident, $($t:tt)*) => {
        trait $traitname : $($t)* {}
        impl<T> $traitname for T where T: $($t)* {}
    }
}

所有这一切都可以通过trait aliases 完成。

此外,我开始只在实际需要的地方要求 trait bound。例如。在很多情况下,struct-definition 本身不依赖于特征边界,只依赖于impl,所以我开始在struct 上省略它们,只将它们保留在impl 中。

【讨论】:

    【解决方案2】:

    您可以为此使用新的特征和一揽子实现:

    use serde::Serialize;
    use serde::de::DeserializeOwned;
    use std::marker::Unpin;
    
    pub trait AppState {}
    pub trait AppEvent {}
    
    pub trait StateTrait : AppState + Clone + Serialize + DeserializeOwned + Unpin + 'static {}
    impl<T : AppState + Clone + Serialize + DeserializeOwned + Unpin + 'static> StateTrait for T {}
    pub trait EventTrait : AppEvent + Clone + Serialize + DeserializeOwned + Unpin + 'static {}
    impl<T : AppEvent + Clone + Serialize + DeserializeOwned + Unpin + 'static> EventTrait for T {}
    
    pub struct IncomingClientMessageWithAddress<State, Msg>
        where State: StateTrait, Msg: EventTrait
    {
        ... 
    }
    

    playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多