gpt4 book ai didi

rust - 带有HashMap的“temporary value dropped while borrowed” <&str,&dyn Fn(&str)-> bool>

转载 作者:行者123 更新时间:2023-12-03 11:44:15 32 4
gpt4 key购买 nike

我有一个函数的字符串的HashMap。根据我的理解,&dyn Fn(&str) -> bool是必需的,因为我想同时使用函数和闭包,但是我遇到了此编译错误:

error[E0716]: temporary value dropped while borrowed
--> src/test.rs:22:26
|
22 | checks.insert("k3", &|i| cached_regex.is_match(i));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
...
27 | match checks.get(kvp[0]) {
| ------ borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
示例代码:
use regex::Regex;
use std::collections::HashMap;

fn main() {
assert_eq!(run_checks("k1:test, k3:1234"), true);
assert_eq!(run_checks("k1:test, k3:12345"), false);
assert_eq!(run_checks("k1:test, k2:test2"), true);
}

fn specific_check(i: &str) -> bool { i == "test" }

fn run_checks(input: &str) -> bool {
let cached_regex = Regex::new(r"^\d{4}$").unwrap();

let mut checks: HashMap<&str, &dyn Fn(&str) -> bool> = HashMap::new();
checks.insert("k1", &specific_check);
checks.insert("k2", &|i| i == "test2");

// Not working
checks.insert("k3", &|i| cached_regex.is_match(i));

for kvp_pair in input.split(",") {
let kvp: Vec<&str> = kvp_pair.trim().split(":").collect();

match checks.get(kvp[0]) {
Some(check) => {
if !check(kvp[1]) {
return false;
}
}
None => return false,
}
}

true
}

最佳答案

解决此问题的最直接的方法是Box dyn Fn(&str) -> bool特征对象。固定的工作示例:

use regex::Regex;
use std::collections::HashMap;

fn main() {
assert_eq!(run_checks("k1:test, k3:1234"), true);
assert_eq!(run_checks("k1:test, k3:12345"), false);
assert_eq!(run_checks("k1:test, k2:test2"), true);
}

fn specific_check(i: &str) -> bool { i == "test" }

fn run_checks(input: &str) -> bool {
let cached_regex = Regex::new(r"^\d{4}$").unwrap();

let mut checks: HashMap<&str, Box<dyn Fn(&str) -> bool>> = HashMap::new();
checks.insert("k1", Box::new(specific_check));
checks.insert("k2", Box::new(|i| i == "test2"));

// now works
checks.insert("k3", Box::new(|i| cached_regex.is_match(i)));

for kvp_pair in input.split(",") {
let kvp: Vec<&str> = kvp_pair.trim().split(":").collect();

match checks.get(kvp[0]) {
Some(check) => {
if !check(kvp[1]) {
return false;
}
}
None => return false,
}
}

true
}
playground

解决方案背后的详细说明
此行中的类型注释不完整,因为省略了引用和trait对象本身的生存期:
let mut checks: HashMap<&str, &dyn Fn(&str) -> bool> = HashMap::new();
给定您插入 checks的键和值,Rust会推断 checks的完整类型为 HashMap<&'static str, &'static (dyn for<'a> Fn(&'a str) -> bool + 'static)>。前两个插入匹配此类型签名,但最后三个不匹配。第三次插入中使用的值的类型为 &'static (dyn for<'a> Fn(&'a str) -> bool + 'b),其中 'b表示捕获的 cached_regex变量的生存期。 Rust引发编译器错误的原因是因为创建具有非 'static生存期的某种类型的 'static引用是无效的,因为该引用可能会失效。将特征对象装箱可以避免此问题,因为我们不再需要为其创建 'static引用,因此不再要求trait对象本身必须存在于 'static中,并且可以安全地完成最后的第三次插入。

关于rust - 带有HashMap的“temporary value dropped while borrowed” <&str,&dyn Fn(&str)-> bool>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65170536/

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