在字符串上创建闭包返回迭代器
Create closure returning iterator on string
我想写一个闭包,它接受一个对象和 returns 它的一个迭代器。这个想法是将闭包存储在一个结构中并根据需要应用:
fn main() {
let iter_wrap = |x: &String| Box::new(x.chars());
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
这会导致错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:2:45
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 2:21...
--> src/main.rs:2:21
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:2:43
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^
note: but, the lifetime must be valid for the call at 5:14...
--> src/main.rs:5:14
|
5 | for x in iter_wrap(&test) {
| ^^^^^^^^^^^^^^^^
note: ...so that argument is valid for the call
--> src/main.rs:5:14
|
5 | for x in iter_wrap(&test) {
| ^^^^^^^^^^^^^^^^
我试过把String
改成Vec
,去掉装箱,结果还是一样。
如何让它编译?
我不完全确定你试图在那里实现什么,但基本上只是看看你提供的例子,你不需要闭包,而是一个函数:
use std::str::Chars;
fn main() {
fn iter_wrap(s: &str) -> Chars {
s.chars()
}
let test = "test".to_string();
for c in iter_wrap(&test) {
println!("{}", c);
}
}
或者你可以有一个闭包,即封闭外部世界,在这种情况下,你的字符串:
fn main() {
let test = "test".to_string();
let iter_wrap = || test.chars();
for c in iter_wrap() {
println!("{}", c);
}
}
在参数或 return 类型中借用的闭包有一些已知错误,如本问题报告所示,以及它链接到的其他错误:https://github.com/rust-lang/rust/issues/58052
有几种方法可以解决此问题。
fn main() {
let iter_wrap = |x| Box::new(str::chars(x));
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
Using a type annotation in the closure body
fn main() {
let iter_wrap = |x| {let x: &String = x; Box::new(x.chars()) };
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
您需要定义和使用比函数本身的生命周期更短的生命周期。我尝试了这个并且成功了:
fn foo<'a, 'b: 'a>() {
let test = String::from("test");
let iw = |x: &'b String| {
x.chars()
};
for x in iw(&test) {
println!("{}", x);
}
}
fn main() {
foo()
}
仅仅使用生命周期 'a
是不够的,你需要比它短 的生命周期,所以 'b: 'a
。
现在我无法解释的是,在定义了 'a 和 'b 的情况下,在闭包定义中使用 &'a String
也同样有效 ...
我想写一个闭包,它接受一个对象和 returns 它的一个迭代器。这个想法是将闭包存储在一个结构中并根据需要应用:
fn main() {
let iter_wrap = |x: &String| Box::new(x.chars());
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
这会导致错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:2:45
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 2:21...
--> src/main.rs:2:21
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:2:43
|
2 | let iter_wrap = |x: &String| Box::new(x.chars());
| ^
note: but, the lifetime must be valid for the call at 5:14...
--> src/main.rs:5:14
|
5 | for x in iter_wrap(&test) {
| ^^^^^^^^^^^^^^^^
note: ...so that argument is valid for the call
--> src/main.rs:5:14
|
5 | for x in iter_wrap(&test) {
| ^^^^^^^^^^^^^^^^
我试过把String
改成Vec
,去掉装箱,结果还是一样。
如何让它编译?
我不完全确定你试图在那里实现什么,但基本上只是看看你提供的例子,你不需要闭包,而是一个函数:
use std::str::Chars;
fn main() {
fn iter_wrap(s: &str) -> Chars {
s.chars()
}
let test = "test".to_string();
for c in iter_wrap(&test) {
println!("{}", c);
}
}
或者你可以有一个闭包,即封闭外部世界,在这种情况下,你的字符串:
fn main() {
let test = "test".to_string();
let iter_wrap = || test.chars();
for c in iter_wrap() {
println!("{}", c);
}
}
在参数或 return 类型中借用的闭包有一些已知错误,如本问题报告所示,以及它链接到的其他错误:https://github.com/rust-lang/rust/issues/58052
有几种方法可以解决此问题。
fn main() {
let iter_wrap = |x| Box::new(str::chars(x));
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
Using a type annotation in the closure body
fn main() {
let iter_wrap = |x| {let x: &String = x; Box::new(x.chars()) };
let test = String::from("test");
for x in iter_wrap(&test) {
println!("{}", x);
}
}
您需要定义和使用比函数本身的生命周期更短的生命周期。我尝试了这个并且成功了:
fn foo<'a, 'b: 'a>() {
let test = String::from("test");
let iw = |x: &'b String| {
x.chars()
};
for x in iw(&test) {
println!("{}", x);
}
}
fn main() {
foo()
}
仅仅使用生命周期 'a
是不够的,你需要比它短 的生命周期,所以 'b: 'a
。
现在我无法解释的是,在定义了 'a 和 'b 的情况下,在闭包定义中使用 &'a String
也同样有效 ...