我正在实现一个简单的图书馆系统来跟踪我的 pdf 文件。
我有一个Subject枚举和一个Entry结构体,定义如下:
pub enum Subject {
Math,
Programming,
CompSci,
Language,
Misc,
None
}
pub struct Entry {
pub subject: Subject
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试实现一个函数,该函数将对 的向量进行操作Entry并返回Vec<&Entry>其条目与给定的匹配的a Subject。
我有一个简单的Library结构,它是 a 的包装器Vec<Entry>:
pub struct Library {
pub entries: Vec<Entry>
}
Run Code Online (Sandbox Code Playgroud)
为此,我需要迭代entries并且仅遍历其字段对应于所需的filter元素。为了实现这一点,我创建了一个将返回谓词函数的函数。.subjectsubject
这是get_subject函数:
impl Library {
pub fn get_subject(&self, subject: Subject) -> Vec<&Entry> {
let pred = subject_pred(subject);
self.entries.iter().filter(pred).collect::<Vec<&Entry>>()
}
}
Run Code Online (Sandbox Code Playgroud)
它调用该函数subject_pred来创建正确的谓词函数:
// Return a PREDICATE that returns true when
// the passed ENTRY matches the desired SUBJECT
fn subject_pred(subject_UNUSED: Subject) -> impl FnMut(&&Entry) -> bool {
|e: &&Entry| if matches!(&e.subject, subject_UNUSED) {
true
} else {
false
}
}
Run Code Online (Sandbox Code Playgroud)
问题就在这里。这个语法编译得很好,但显然subject_UNUSED局部变量subject_pred是“未使用的”。我大吃一惊,因为我的语法清楚地表明了与传递的subject_UNUSED. 当我在条目向量上测试此函数时,谓词始终返回 true(因此我收到“未使用”警告),但我实际上不知道为什么。
如果有人能解释为什么该match语句总是匹配的,那将不胜感激。我尝试使用常规match语句,但弹出了相同的警告,这不是我尝试编码的行为。如果我不在subject_UNUSED传统match语句中包含 ,编译器会告诉我必须覆盖枚举的Math、Programming、CompSci、Language和变体,这向我表明直到该点为止的一切都很好。MiscNone
您无法匹配变量。你所做的相当于
matches!(&e.subject, some_subject)
Run Code Online (Sandbox Code Playgroud)
它匹配任何 Subject,就像通配符 ( _) 一样,但它也在变量中捕获它some_subject(可以在像 这样的防护中使用matches!(&e.subject, subject_UNUSED if subject_UNUSED == ...))。捕获的变量和参数(被它遮挡)都不会被使用。
您需要做的是#[derive(PartialEq)]然后使用==:
if e.subject == subject_UNUSED { ... }
Run Code Online (Sandbox Code Playgroud)
顺便说一句,您的代码还存在其他问题:您没有move进入闭包,并且您正在获取拥有的条目,但产生借用的条目。