gpt4 book ai didi

rust - `.map(f)` 和 `.map(|x| f(x))` 有什么区别?

转载 作者:行者123 更新时间:2023-12-04 16:24:37 25 4
gpt4 key购买 nike

做的时候rustlings standard_library_types/iterators2.rs ,我开始想知道如何 std::iter::Iterator::map 调用它的参数闭包/函数。更具体地说,假设我有一个功能

// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
None => String::new(),
Some(first) => String::from(first.to_ascii_uppercase()) + c.as_str(),
}
}
现在我想用它
// Apply the `capitalize_first` function to a slice of string slices.
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
words.into_iter().map(capitalize_first).collect()
}
哪个不编译
error[E0631]: type mismatch in function arguments
--> exercises/standard_library_types/iterators2.rs:24:27
|
11 | pub fn capitalize_first(input: &str) -> String {
| ---------------------------------------------- found signature of `for<'r> fn(&'r str) -> _`
...
24 | words.into_iter().map(capitalize_first).collect()
| ^^^^^^^^^^^^^^^^ expected signature of `fn(&&str) -> _`

error[E0599]: the method `collect` exists for struct `Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>`, but its trait bounds were not satisfied
--> exercises/standard_library_types/iterators2.rs:24:45
|
24 | words.into_iter().map(capitalize_first).collect()
| ^^^^^^^ method cannot be called on `Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<for<'r> fn(&'r str) -> String {capitalize_first} as FnOnce<(&&str,)>>::Output = _`
which is required by `Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>: Iterator`
`for<'r> fn(&'r str) -> String {capitalize_first}: FnMut<(&&str,)>`
which is required by `Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>: Iterator`
`Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>: Iterator`
which is required by `&mut Map<std::slice::Iter<'_, &str>, for<'r> fn(&'r str) -> String {capitalize_first}>: Iterator`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0599, E0631.
For more information about an error, try `rustc --explain E0599`.
但是,我更改后它工作正常 .map(capitalize_first).map(|x| capitalize_first(x)) .显然,Rust 在将每个项目传递给 map 的参数闭包/函数之前借用(不确定是可变还是不可变)每个项目。 ,这是有道理的,因为我们通常不想消耗被迭代的对象。
我无法理解的是,为什么 Rust 不借用参数给 |x| capitalize_first(x) .我假设关闭 |x| capitalize_first(x)还有 &&str ,然后是 auto-dereferencing rules启动并将其取消引用为 &str ,但这并不能解释为什么当我使用函数 capitalize_first 时它没有启动. .map(|x| capitalize_first(x))有什么区别和 .map(capitalize_first) ?考虑到 map 的参数,这里是否发生动态调度?是一个特质对象吗?
注:此问题与 Using a function with iter().map() - as a named function vs as a closure 不重复因为我在问为什么,而另一个帖子问的是如何。关于该问题的公认答案,如果有人能解释为什么我们需要 AsRef,我将不胜感激。而 Rust 已经拥有 auto-dereferencing rules .

最佳答案

为什么我可以调用capitalize_first&&str争论?
auto-dereferencing rules 的链接问答专为如何self使用 a.b() 时已解决句法。参数规则一般跳过自动引用步骤,只依赖于 Deref coercions .自 &&str工具Deref<Target = &str> (实际上所有引用都实现了 Deref ),这个 &&str -> &str转变是透明的。
为什么它不适用于 .map()然后?
简单明了,map()期待实现 Fn(&&str) -> T 的东西和 capitalize_first才不是。 A Fn(&str)没有透明地转化为Fn(&&str) ,它需要一个类似于闭包引入的转换步骤(尽管是透明的)。

关于rust - `.map(f)` 和 `.map(|x| f(x))` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67864911/

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