gpt4 book ai didi

rust - 为什么传递给 flat_map 的闭包没有类型注释可以编译,而带有注释的闭包却不能?

转载 作者:行者123 更新时间:2023-11-29 08:05:14 26 4
gpt4 key购买 nike

为什么在闭包上没有类型注释的情况下可以编译?

fn transform(input: &Vec<Vec<String>>) {
input.iter().flat_map(|words| words.iter());
}

但这不是吗?

fn transform(input: &Vec<Vec<String>>) {
input.iter().flat_map(|words: &Vec<String>| words.iter());
}

推断类型不是&Vec<String>吗?或者我是否也需要注释生命周期,因为这似乎与闭包的生命周期不够长有关?

后一段的错误是

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:2:55
|
2 | input.iter().flat_map(|words: &Vec<String>| words.iter());
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 2:48...
--> src/main.rs:2:49
|
2 | input.iter().flat_map(|words: &Vec<String>| words.iter());
| ^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:2:49
|
2 | input.iter().flat_map(|words: &Vec<String>| words.iter());
| ^^^^^
note: but, the lifetime must be valid for the method call at 2:4...
--> src/main.rs:2:5
|
2 | input.iter().flat_map(|words: &Vec<String>| words.iter());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so type `fn(std::slice::Iter<'_, std::vec::Vec<std::string::String>>, [closure@src/main.rs:2:27: 2:61]) -> std::iter::FlatMap<std::slice::Iter<'_, std::vec::Vec<std::string::String>>, std::slice::Iter<'_, std::string::String>, [closure@src/main.rs:2:27: 2:61]> {<std::slice::Iter<'_, std::vec::Vec<std::string::String>> as std::iter::Iterator>::flat_map::<std::slice::Iter<'_, std::string::String>, [closure@src/main.rs:2:27: 2:61]>}` of expression is valid during the expression
--> src/main.rs:2:5
|
2 | input.iter().flat_map(|words: &Vec<String>| words.iter());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

最佳答案

编译器担心您的代码会产生悬挂指针。当您离开类型注释时,编译器会正确推断出内部引用相对于外部引用的生命周期。

但是,当您注释类型并且不要向编译器解释内部引用的生命周期如何与外部引用相关(即,words: &Vec<String>/内部引用如何相关到 input: &Vec<Vec<String>>/外部引用),编译器吓坏了。

简单的解决方法是让编译器知道内部引用的生命周期至少与外部引用的生命周期相同:

fn transform<'a>(input: &'a Vec<Vec<String>>) {
input.iter().flat_map(|words: &'a Vec<String>| words.iter());
}

希望这是有道理的。在 Rust 中,引用不能比它引用的内容长寿。在编译器眼中,你的 input引用可能会在您的 words 之前消失引用确实如此(这很糟糕,因为 words 引用了 input 中的项目)。因此,如果您不打算让编译器推断生命周期,则需要明确说明。

关于rust - 为什么传递给 flat_map 的闭包没有类型注释可以编译,而带有注释的闭包却不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41049270/

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