我想为包含IntoIterator
的结构实现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
});
}
}
预期输出: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
字符迭代器应该与StringStruct::system_string
具有相同的生命周期,但我不知道如何表达这一点,或者这种方法是否可行。
答案 0 :(得分:5)
要回答您提出的问题,我建议impl IntoIterator for &StringStruct
(引用到StringStruct
而不是直接结构)。代码如下所示:
impl<'a> IntoIterator for &'a StringStruct {
type Item = u32;
type IntoIter = Map<Chars<'a>, Fn(char) -> u32>;
// ...
}
但是,您会发现许多更多错误之后会有不同的来源。弹出的下一个错误是Fn(char) -> u32
在编译时没有常量大小。
问题是您尝试通过编写Fn(char) -> u32
来命名闭包的类型。但这不是不是闭包的类型,而只是闭包实现的特征。闭包的类型不能命名为(有时称为“伏地级类型”)。
这意味着,您现在无法指定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);
}
}
只是一个小注释:一个明确的return
在没有必要时被认为是Rust中的坏风格。通过尽可能删除return
来更好地坚持规则并编写惯用代码; - )