【问题标题】:Is it possible to combine type constraints in Rust?是否可以在 Rust 中组合类型约束?
【发布时间】:2021-12-16 11:22:03
【问题描述】:

我一直在使用相当多的静态类型编程语言(C++、Haskell、...),但对 Rust 比较陌生。

我经常这样写代码:

struct LeafNode<K: Ord + Default + Clone, V: Default + Clone> {
  keys: Vec<K>,
  values: Vec<V>,
}

impl <K: Ord + Default + Clone, V: Default + Clone> LeafNode<K, V> {
  // ...
}

这里的类型约束有很多重复。 当LeafNode 在其他东西中使用时(例如,在构建节点树时),这种情况会更加复杂。 每当这些约束之一在实施过程中发生变化时,有许多地方需要更改代码,因为它们在许多不同的struct 定义和impl 块中命名。

有没有办法从K: Ord + Default + CloneV: Default + Clone 创建某种“类型约束别名”?

如果它存在,它可能有一些我不知道的名字,这使得搜索这种技术非常困难。因此提出了这个问题。

【问题讨论】:

  • 好吧,您不需要约束结构,只需使用 impl 就足够了(通常),这将为您节省 50% 的约束声明 :)
  • @Netwave 有趣!什么时候什么时候不需要约束结构本身?
  • @Qqwy 有关何时在结构上使用边界的更多详细信息,请参阅this question

标签: generics rust type-constraints


【解决方案1】:

您可以通过创建自己的 trait 来实现这一点,该 trait 以其他 trait 为界限,然后为其添加一个全面的实现:

trait MyConstraint: Ord + Default + Clone {}
impl <T: Ord + Default + Clone> MyConstraint for T {}

struct LeafNode<K: MyConstraint> {
    keys: Vec<K>
}

impl<K: MyConstraint> LeafNode<K> {
    fn keys(&self) -> &[K] {
        &self.keys
    }
}

【讨论】:

    【解决方案2】:

    作为补充答案。

    可以使用trait alias(目前不稳定):

    #![feature(trait_alias)]
    
    trait MyConstraint = Ord + Default + Clone;
    
    struct LeafNode<K: MyConstraint> {
        keys: Vec<K>
    }
    
    impl<K: MyConstraint> LeafNode<K> {
        fn keys(&self) -> &[K] {
            &self.keys
        }
    }
    

    Playground

    【讨论】:

      猜你喜欢
      • 2020-02-12
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多