gpt4 book ai didi

types - 在火柴臂中创建闭包

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

我正在阅读 Rust Book 并一直在调整“minigrep”项目,这样我就没有同时拥有 searchsearch_case_insensitive 功能,而是拥有一个 search 函数,它采用指定区分大小写的枚举。这就是我所拥有的:

pub fn search<'a>(query: &str, contents: &'a str, case: &Case) -> Vec<&'a str> {
match case {
Case::Sensitive => contents
.lines()
.filter(|line| line.contains(query))
.collect(),

Case::Insensitive => {
let query = query.to_lowercase();

contents
.lines()
.filter(|line| line.to_lowercase().contains(&query))
.collect()
}
}
}

我想我会尝试重写它,以使用闭包删除重复的逻辑。然而,这会导致各种类型检查问题。我的第一次尝试:

let query_lower = query.to_lowercase();

let filter = match case {
Case::Sensitive => |line| line.contains(query),
Case::Insensitive => |line| line.to_lowercase().contains(&query_lower)
};

我很快了解到不同的闭包具有不同的类型,即使它们具有相同的签名。我读到装箱关闭可能会有所帮助:

let filter: Box<dyn Fn(&str) -> bool> = match case {
Case::Sensitive => Box::new(|line| line.contains(query)),
Case::Insensitive => Box::new(|line| line.to_lowercase().contains(&query_lower))
};

这确实解决了 ARM 类型不匹配的 match,但是现在 .filter 提示它的参数是不正确的类型,现在我陷入了困境:

error[E0277]: expected a `FnMut<(&&str,)>` closure, found `dyn for<'r> Fn(&'r str) -> bool`
--> src/lib.rs:27:17
|
27 | .filter(filter)
| ^^^^^^ expected an `FnMut<(&&str,)>` closure, found `dyn for<'r> Fn(&'r str) -> bool`
|
= help: the trait `FnMut<(&&str,)>` is not implemented for `dyn for<'r> Fn(&'r str) -> bool`
= note: required because of the requirements on the impl of `for<'r> FnMut<(&'r &str,)>` for `Box<dyn for<'r> Fn(&'r str) -> bool>`

以这种方式使用闭包是不是一个好主意,因为类型规则,或者我只是出于天真而错误地“装箱”了东西?

最佳答案

filter闭包的类型必须是 FnMut(&Self::Item) -> bool因为你有一个 Iterator<Item = &str> &Self::Item变成 &&str .所以而不是 Box<dyn Fn(&str) -> bool>你应该使用 Box<dyn Fn(&&str) -> bool :

enum Case {
Sensitive,
Insensitive,
}

fn search<'a>(query: &str, contents: &'a str, case: &Case) -> Vec<&'a str> {
let query_lower = query.to_lowercase();

let filter: Box<dyn Fn(&&str) -> bool> = match case {
Case::Sensitive => Box::new(|line| line.contains(query)),
Case::Insensitive => Box::new(|line| line.to_lowercase().contains(&query_lower)),
};

contents.lines().filter(filter).collect()
}

playground

这是有效的,因为所有 Fn类型也是 FnMut .

关于types - 在火柴臂中创建闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66050177/

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