web*_*tee 5 iterator traits lifetime rust
我想为IntoIterator包含a的结构实现trait String.迭代器基于chars()迭代器,应该计算'1'字符并累积结果.这是我到目前为止的简化版本:
use std::iter::Map;
use std::str::Chars;
fn main() {
let str_struct = StringStruct { system_string: String::from("1101") };
for a in str_struct {
println!("{}", a);
}
}
struct StringStruct {
system_string: String
}
impl IntoIterator for StringStruct {
type Item = u32;
type IntoIter = Map<Chars, Fn(char) -> u32>;
fn into_iter(self) -> Self::IntoIter {
let count = 0;
return self.system_string.chars().map(|c| match c {
Some('1') => {
count += 1;
return Some(count);
},
Some(chr) => return Some(count),
None => return None
});
}
}
Run Code Online (Sandbox Code Playgroud)
预期产量: 1, 2, 2, 3
这失败了:
error[E0107]: wrong number of lifetime parameters: expected 1, found 0
--> src/main.rs:17:25
|
17 | type IntoIter = Map<Chars, Fn(char) -> u32>;
| ^^^^^ expected 1 lifetime parameter
Run Code Online (Sandbox Code Playgroud)
字符迭代器应该具有相同的生命周期StringStruct::system_string,但我不知道如何表达这个或者这种方法是否可行.
要回答你问的问题,我建议impl IntoIterator for &StringStruct(直接引用一个StringStruct结构代替结构).代码如下所示:
impl<'a> IntoIterator for &'a StringStruct {
type Item = u32;
type IntoIter = Map<Chars<'a>, Fn(char) -> u32>;
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是,您会注意到之后有更多不同来源的错误.弹出的下一个错误是Fn(char) -> u32在编译时没有常量大小.
问题是您尝试通过编写来命名闭包的类型Fn(char) -> u32.但这不是你的闭包的类型,而只是闭包实现的特征.无法命名闭包的类型(有时称为"Voldemort类型").
这意味着,您现在无法指定Map<_, _>对象的类型.这是一个已知的问题; 最近接受的impl Trait-RFC可能会为此类案例提供解决方法.但是现在,这是不可能的,对不起.
那么如何解决呢?您需要创建自己的类型来实现Iterator和使用它而不是Map<_, _>.请注意,您仍然可以使用Chars迭代器.这是完整的解决方案:
struct StringStructIter<'a> {
chars: Chars<'a>,
count: u32,
}
impl<'a> Iterator for StringStructIter<'a> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
self.chars.next().map(|c| {
if c == '1' {
self.count += 1;
}
self.count
})
}
}
impl<'a> IntoIterator for &'a StringStruct {
type Item = u32;
type IntoIter = StringStructIter<'a>;
fn into_iter(self) -> Self::IntoIter {
StringStructIter {
chars: self.system_string.chars(),
count: 0,
}
}
}
fn main() {
let str_struct = StringStruct { system_string: String::from("1101") };
for a in &str_struct {
println!("{}", a);
}
}
Run Code Online (Sandbox Code Playgroud)
而且只是一个小小的注释:return在不必要的情况下明确表示Rust中的不良风格.通过return尽可能删除来更好地坚持规则并编写惯用代码;-)
| 归档时间: |
|
| 查看次数: |
277 次 |
| 最近记录: |