在Rust中是否可能结合使用类型约束?

6

我在多个静态类型编程语言(如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 创建某种“类型约束别名”?

如果存在这样的方法,它可能有我不知道的名称,这使得搜索这种技术非常困难。因此出现了这个问题。


2
好的,你不需要限制结构体,只有实现就足够了(通常情况下),这将为你节省50%的约束声明 :) - Netwave
@Netwave 有趣!何时需要对结构体本身进行约束,何时不需要? - Qqwy
1
@Qqwy 请参考此问题以了解何时在结构体上使用边界的更多细节。 - Filipe Rodrigues
2个回答

8
你可以通过创建自己的trait并将其他traits作为约束条件来实现这一点,然后为其添加一个全局实现:
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
    }
}

3
作为补充答案。
你可以使用特性别名(目前不稳定):
#![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
    }
}

游乐场


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接