gpt4 book ai didi

rust - 如何创建一个以函数引用为值的 lazy_static HashMap?

转载 作者:行者123 更新时间:2023-11-29 07:47:45 30 4
gpt4 key购买 nike

我尝试创建一个 HashMap 并将函数作为值:

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
static ref HASHES: HashMap<&'static str, &'static Fn([u8])> = {
let mut m = HashMap::new();
m.insert("md5", &md5);
m
};
}

fn md5(bytes: &[u8]) -> String {
String::default()
}

编译器给我一个错误:

error[E0277]: the trait bound `std::ops::Fn([u8]) + 'static: std::marker::Sync` is not satisfied in `&'static std::ops::Fn([u8]) + 'static`
--> src/main.rs:6:1
|
6 | lazy_static! {
| _^ starting here...
7 | | static ref HASHES: HashMap<&'static str, &'static Fn([u8])> = {
8 | | let mut m = HashMap::new();
9 | | m.insert("md5", &md5);
10 | | m
11 | | };
12 | | }
| |_^ ...ending here: within `&'static std::ops::Fn([u8]) + 'static`, the trait `std::marker::Sync` is not implemented for `std::ops::Fn([u8]) + 'static`
|
= note: `std::ops::Fn([u8]) + 'static` cannot be shared between threads safely
= note: required because it appears within the type `&'static std::ops::Fn([u8]) + 'static`
= note: required because of the requirements on the impl of `std::marker::Sync` for `std::collections::hash::table::RawTable<&'static str, &'static std::ops::Fn([u8]) + 'static>`
= note: required because it appears within the type `std::collections::HashMap<&'static str, &'static std::ops::Fn([u8]) + 'static>`
= note: required by `lazy_static::lazy::Lazy`
= note: this error originates in a macro outside of the current crate

我不明白我应该怎么做才能修复这个错误,我不知道创建这样一个 HashMap 的任何其他方法。

最佳答案

您的代码有多个问题。编译器出现的错误告诉您您的代码将允许内存不安全:

`std::ops::Fn([u8]) + 'static` cannot be shared between threads safely

您存储在 HashMap 中的类型不能保证它可以被共享。

您可以通过将您的值类型更改为 &'static (Fn([u8]) + Sync) 来指定这样的界限来“修复”这个问题。由于您的函数签名不匹配,这将解锁下一个错误:

expected type `std::collections::HashMap<&'static str, &'static std::ops::Fn([u8]) + std::marker::Sync + 'static>`
found type `std::collections::HashMap<&str, &fn(&[u8]) -> std::string::String {md5}>`

“修复”&'static (Fn(&[u8]) -> String + Sync) 会导致深奥的生命周期错误:

expected type `std::collections::HashMap<&'static str, &'static for<'r> std::ops::Fn(&'r [u8]) -> std::string::String + std::marker::Sync + 'static>`
found type `std::collections::HashMap<&str, &fn(&[u8]) -> std::string::String {md5}>`

这可以通过将带有 &md5 的函数转换为 &'static (Fn(&[u8]) -> String + Sync)) 来“修复”,这会导致

note: borrowed value must be valid for the static lifetime...
note: consider using a `let` binding to increase its lifetime

这是因为 the reference you've made is to a temporary value that doesn't live outside of the scope 触底反弹.


我将 fix 放在引号中,因为这不是真正正确的解决方案。正确的做法是只使用函数指针:

lazy_static! {
static ref HASHES: HashMap<&'static str, fn(&[u8]) -> String> = {
let mut m = HashMap::new();
m.insert("md5", md5 as fn(&[u8]) -> std::string::String);
m
};
}

老实说,我会说 HashMap 可能有点矫枉过正;我会使用一个数组。小型数组可能比小型 HashMap 更快:

type HashFn = fn(&[u8]) -> String;

static HASHES: &'static [(&'static str, HashFn)] = &[
("md5", md5),
];

您可以从遍历列表开始,或者花点时间将其按字母顺序排列,然后使用 binary_search当它变大时。

关于rust - 如何创建一个以函数引用为值的 lazy_static HashMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43307019/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com