#rust
#Ржавчина
Вопрос:
Я хочу сохранить функцию внутри Hashmap в rust, но я не знаю, как «получить» ее и вызвать в другом месте. Вот что я пробовал
type Ihello = fn() -> String;
fn main() {
use std::collections::HashMap;
let mut mapp: HashMap<String, Ihello> = HashMap::new();
mapp.insert(
"hello".to_string(),
hello
);
let hello_string = "hello".to_string();
let hello: Option<amp;Ihello> = book_reviews.get(amp;hello_string);
}
fn hello() -> String {
String::from("HELLOHELLOHELLO")
}
Я хочу позже «вызвать» функцию hello, есть ли какой-нибудь способ это сделать?
или есть альтернативный способ сделать это?
Ответ №1:
HashMap.get
возвращает Option<amp;Ihello>
, что означает, что результатом может быть либо Some
значение Ihello
, либо None
(если ключ не существует). Итак, одним из решений является разрушение оператора Option
if let
using.
let hello: Option<amp;Ihello> = mapp.get(amp;hello_string);
if let Some(val) = hello {
println!("{}", val()); // calling the function here
} else {
println!("Key is missing!");
}
Ответ №2:
Вы можете использовать a Box
для хранения ссылки на функцию, а затем вызвать функцию, которую map.get(...).unwrap()
возвращает (обратите внимание, что у нас есть ()()
в последней строке).
use std::collections::HashMap;
type Ihello = dyn Fn() -> String;
fn hello() -> String {
"HELLO".to_string()
}
fn main() {
let mut map: HashMap<amp;str, Box<Ihello>> = HashMap::new();
map.insert("hello", Box::new(hello));
println!("{}", map.get("hello").unwrap()());
}
Комментарии:
1. Боксирование признака Fn поможет сохранить замыкания в HashMap (в дополнение к обычным функциям), но поскольку это не проблема пользователя, это кажется отвлекающим фактором.
2. @hkBst согласился, но стоит отметить, что
fn() -> String
это будет поддерживать только функции, в то время как что-то вродеBox<dyn FnMut() -> String>
также поддерживает замыкания. На самом деле, ИМХО, последнее здесь более уместно.