Vector 如何过滤Rust中自定义结构的向量?

Vector 如何过滤Rust中自定义结构的向量?,vector,struct,rust,filtering,Vector,Struct,Rust,Filtering,我正在尝试筛选一个Vec,其中词汇表是一个自定义结构,它本身包含一个struct VocabularyMetadata和一个Vec: 这是行不通的。我得到的错误是: the trait `std::iter::FromIterator<&app_structs::Vocabulary>` is not implemented for `std::vec::Vec<app_structs::Vocabulary>` [E0277] 所以字符串似乎实现了FromI

我正在尝试筛选一个Vec,其中词汇表是一个自定义结构,它本身包含一个struct VocabularyMetadata和一个Vec:

这是行不通的。我得到的错误是:

 the trait `std::iter::FromIterator<&app_structs::Vocabulary>` is not implemented for `std::vec::Vec<app_structs::Vocabulary>` [E0277]
所以字符串似乎实现了FromIterator

但是,我不明白为什么我不能简单地从filter或collect方法中获取Vec的元素

如何过滤我的Vec并简单地获得Vec的元素,条件为真?

学习如何创建一个。您的问题可以归结为:

struct Vocabulary;

fn main() {
    let numbers = vec![Vocabulary];
    let other_numbers: Vec<Vocabulary> = numbers.iter().collect();
}
如果有可变引用,也可以耗尽迭代器:

let the_vocabulary: Vec<Vocabulary> = vocabulary_context
    .vocabularies
    .drain(..)
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .collect();
不收集值,收集引用的向量。这要求无论您以后如何使用项目,都可以通过引用而不是通过值获取项目:

let the_vocabulary: Vec<&Vocabulary> = vocabulary_context
    .vocabularies
    .iter()
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .collect();
注意,我删除了多余的类型说明符turbofish::on collect。您只需要指定变量的类型或collect上的类型,而不是两者都指定。事实上,所有三个示例都可以从let_词汇表:Vec开始,让编译器根据迭代器推断集合中的类型。这是惯用的风格,但为了演示,我保留了显式类型

另见:


我现在明白了这一点,但很重要。完全忽略了这一点。我不理解使用词汇表的引用,而只是在引用处给我对象的问题。是关于对象结构的未知大小,包含另一个Vec等吗。?对我来说,只有第一个解决方案1起作用,因为2 std::clone::clone也不满足,3仍然是不匹配的类型:app_structs::词汇表vs&app_structs::词汇表。我会再读一遍。我读到它是破坏性的,实际上想要一个包含元素的副本,所以克隆可能是有意义的。只要在引用处给我对象,你会建议对当前拥有该对象的东西发生什么?如果你取得了所有权,那么它将处于未定义状态,任何进一步的使用都会导致内存不安全。嗯,这很奇怪。我想,因为所有这些都发生在同一个范围内,好吧,也许我在子范围之间借用它,但它们返回所有权无论如何,我不需要担心这样的事情。难道编译器不能理解吗?我的意思是过滤器等毕竟是预定义的函数,这可能是它的原因。你确定这不是关于未知的大小而不是所有权吗?@Zelphir,编译器发现你想从提供&词汇表引用的迭代器中获取Vec。过滤只是一种特征的常用方法。编译器只知道它的签名fn collectself->B,其中B:FromIterator,因此它检查类型Vec是否实现了trait FromIterator,发现它没有实现,并报告错误。我是个新手。你能解释一下或给我看一些资源这意味着什么吗| voc |我来自JS,从未见过这样的东西
struct Vocabulary;

fn main() {
    let numbers = vec![Vocabulary];
    let other_numbers: Vec<Vocabulary> = numbers.iter().collect();
}
let the_vocabulary: Vec<Vocabulary> = vocabulary_context
    .vocabularies
    .into_iter()
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .collect();
let the_vocabulary: Vec<Vocabulary> = vocabulary_context
    .vocabularies
    .drain(..)
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .collect();
let the_vocabulary: Vec<Vocabulary> = vocabulary_context
    .vocabularies
    .iter()
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .cloned()
    .collect();
let the_vocabulary: Vec<&Vocabulary> = vocabulary_context
    .vocabularies
    .iter()
    .filter(|voc| voc.metadata.identifier == vocabulary_id)
    .collect();