I want to pass a method from a struct as a function. I am unsure if I need to change a function signature somewhere or add lifetime parameters- I have tried both but am struggling. Confession: when passing functions as arguments, I don't fully have my head around the difference between Fn() and &dyn Fn() and &impl Fn().
Here is a playground link.
Here is the code:
use std::vec::Vec;
struct Document {
words: Vec<String>,
}
impl Document {
// if a word in the document is 'recognized' by the highlighter function, mark it with HTML bold brackets
fn highlight_me(&mut self, highlighter: &dyn Fn(&str)->bool) {
for word in &mut self.words {
if highlighter(&word) {
*word = format!("<b>{}</b>", word)
}
}
}
}
struct Glossary {
// a list of words you want to highlight if you find them
keywords: Vec<String>
}
impl Glossary {
fn highlight_doc(&self, word: &str) -> bool {
for kw in &self.keywords {
if kw == word {
return true
}
}
false
}
}
fn main() {
let mut doc = Document{words: vec!["How".to_string(), "Foo".to_string(), "works".to_string()]};
let glossary = Glossary{keywords: vec!["Foo".to_string()]};
let closure = |word| glossary.highlight_doc(word);
doc.highlight_me(&closure)
}
And here is the error: again I have tried specifying lifetimes here and there but I a missing something:
39 | doc.highlight_me(&closure)
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 str) -> bool` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`