【问题标题】:Is it possible to have a heterogeneous vector of types that implement Eq?是否有可能拥有实现 Eq 的类型的异构向量?
【发布时间】:2016-11-03 20:53:20
【问题描述】:

我想要一个包含 Eq 等特征的元素的向量,并且我需要异构向量。例如:

let mut x: Vec<Eq> = Vec::new();

x.push(1);
x.push("hello")

我收到一条错误消息,指出无法将Eq 制成对象:

error[E0038]: the trait `std::cmp::Eq` cannot be made into an object
 --> src/main.rs:2:20
  |
2 |     let mut x: Vec<Eq> = Vec::new();
  |                    ^^ the trait `std::cmp::Eq` cannot be made into an object
  |
  = note: the trait cannot use `Self` as a type parameter in the supertrait listing

是否有可能有一个指针列表,指向我可以比较的东西,而不管它们的类型如何?

【问题讨论】:

  • 如果你乐意使用Any trait 而不是EqVec&lt;Box&lt;Any&gt;&gt; 可以工作 (playground link)。
  • 谢谢,但我确实需要能够比较向量中的东西。特别是,更大的问题是我想要一个具有异构键的 HashMap。

标签: rust


【解决方案1】:

是否有可能有一个指针列表,指向我可以比较的东西,而不管它们的类型如何?

这没有意义。您如何“比较”StringFileSocketGuiWindowFontFamily

代码也有一些小问题,即它缺少任何类型的特征间接性。请参阅What is the best way to create a heterogeneous collection of objects?,了解如何在不与对象安全作斗争的情况下制作异构向量。

谈到对象安全there's a great blog series on the subject,其中涵盖了您遇到的特定错误的详细信息。

那么,我们能做些什么呢?对于初学者,我们可以更具体:

let mut x: Vec<Box<PartialEq<u8>>> = Vec::new();

之所以有效,是因为我们说向量中的所有内容都可以与u8 进行比较,并且每个都可以进行比较,并且没有无限数量的可能性。

您还可以实现一些特征来指示事物应该如何进行比较,然后使用它:

trait Silly {
    fn silly(&self) -> usize;
}

impl Silly for u8 {
    fn silly(&self) -> usize { *self as usize }
}

impl Silly for bool {
    fn silly(&self) -> usize { 1 }
}

fn main() {
    let mut x: Vec<Box<Silly>> = Vec::new();
}

【讨论】:

  • 谢谢。比较不同类型的东西很简单,不同类型的值总是不同的,但是相同类型的值可以相等。在我的例子中,我想要实现的是一个 n-ary 树,其中每个级别都有不同类型的键,所以我需要泛型类型参数有点通用,我完全需要 Eq 和 Hash。跨度>
  • @FCo 我们所说的密钥类型是什么?你不能把它们包裹在一个枚举上吗?
  • 枚举是一个很好的解决方案,IMO。然后由数据结构的用户酌情实现Eq
  • 我喜欢枚举的想法,它引导我找到最终的解决方案,即保持树的每一层作为自己独立的数据结构。过于复杂且难以键入的异构键树是错误的方法。
猜你喜欢
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多