Reputation: 49
I am implementing a simple library system to keep track of my pdfs.
I have a Subject
enum and a Entry
struct defined as follows:
pub enum Subject {
Math,
Programming,
CompSci,
Language,
Misc,
None
}
pub struct Entry {
pub subject: Subject
}
I am trying to implement a function that will operate on a vector of Entry
's and return a Vec<&Entry>
whose entries match a given Subject
.
I have a simple Library
struct that is a wrapper around a Vec<Entry>
:
pub struct Library {
pub entries: Vec<Entry>
}
In order to do so, I need to iterate through entries
and filter
only the elements whose .subject
field correspond to the desired subject
. To accomplish this I have created a function that will return a predicate function.
Here is the get_subject
function:
impl Library {
pub fn get_subject(&self, subject: Subject) -> Vec<&Entry> {
let pred = subject_pred(subject);
self.entries.iter().filter(pred).collect::<Vec<&Entry>>()
}
}
which calls the function subject_pred
to create the correct predicate function:
// 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
}
}
Here's the problem. This syntax compiles just fine but apparently the subject_UNUSED
local variable in subject_pred
is "unused". I am flabbergasted as my syntax clearly shows intent to match with the passed subject_UNUSED
. When I test out this function on a vector of entries, the predicate always returns true (hence why I am receiving the "unused" warning) but I have literally no idea why.
If anyone could explain why the match
statement is always matched, that would be greatly appreciated. I tried using a regular match
statement but the same warning is popping up, and this is not the behavior that I am trying to code. If I don't include the subject_UNUSED
in a traditional match
statement, the compiler tells me that I have to cover the Math
, Programming
, CompSci
, Language
, Misc
and None
variants of my enum, which indicates to me that everything up until that point is good.
Upvotes: 3
Views: 1180
Reputation: 70860
You cannot match against a variable. What you've done is equivalent to
matches!(&e.subject, some_subject)
That matches any Subject
, just like a wildcard (_
), except it also captures it in the some_subject
variable (can be used in a guard like matches!(&e.subject, subject_UNUSED if subject_UNUSED == ...)
). Neither the captured variable nor the parameter (which is shadowed by it) are used.
What you need to do is to #[derive(PartialEq)]
then use ==
:
if e.subject == subject_UNUSED { ... }
By the way, your code also has other problems: you don't move
into the closure and you're taking owned entries but produce borrowed.
Upvotes: 8