[英]Wrong number of lifetime parameters when using a modified `Chars` iterator
I want to implement the IntoIterator
trait for a struct containing a String
. 我想为包含
String
的结构实现IntoIterator
特性。 The iterator is based on the chars()
iterator, is supposed to count the '1'
chars and accumulate the result. 迭代器基于
chars()
迭代器,应该计算'1'
字符并累加结果。 This is a simplified version of what I got so far: 这是到目前为止我得到的简化版本:
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
});
}
}
Expected output: 1, 2, 2, 3
预期输出:
1, 2, 2, 3
This fails with: 失败的原因是:
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
The chars iterator should have the same lifetime as the StringStruct::system_string
, but I have no idea how to express this or if this approach is viable at all. 字符迭代器的生存期应与
StringStruct::system_string
,但是我不知道如何表达这种说法,或者这种方法是否可行。
To answer the question you asked, I'd recommend to impl IntoIterator for &StringStruct
(a reference to a StringStruct
instead of the struct directly). 要回答你问的问题,我建议你到
impl IntoIterator for &StringStruct
(一个参考 StringStruct
,而不是直接的结构)。 The code would look like this: 代码如下所示:
impl<'a> IntoIterator for &'a StringStruct {
type Item = u32;
type IntoIter = Map<Chars<'a>, Fn(char) -> u32>;
// ...
}
However, you will notice many more errors that have a different origin afterwards. 但是,之后您会注意到更多错误 ,这些错误的起源不同。 The next error that pops up is that
Fn(char) -> u32
does not have a constant size at compile time. 弹出的下一个错误是
Fn(char) -> u32
在编译时大小没有恒定。
The problem is that you try to name the type of your closure by writing Fn(char) -> u32
. 问题是您尝试通过编写
Fn(char) -> u32
来命名闭包的类型。 But this is not the type of your closure, but merely a trait which is implemented by the closure. 但这不是关闭的类型,而仅仅是关闭所实现的特征。 The type of a closure can't be named (sometimes called "Voldemort type").
闭包的类型无法命名 (有时称为“ Voldemort类型”)。
This means that, right now, you can't specify the type of a Map<_, _>
object. 这意味着,现在您不能指定
Map<_, _>
对象的类型。 This is a known issue; 这是一个已知的问题; the recently accepted
impl Trait
-RFC might offer a workaround for cases like this. 最近接受的
impl Trait
-RFC可能为这种情况提供一种解决方法。 But right now, it's not possible, sorry. 但是现在,不可能,抱歉。
So how to solve it then? 那么如何解决呢? You need to create your own type that implements
Iterator
and use it instead of Map<_, _>
. 您需要创建自己的实现
Iterator
的类型,并使用它代替Map<_, _>
。 Note that you can still use the Chars
iterator. 请注意,您仍然可以使用
Chars
迭代器。 Here is the full solution: 这是完整的解决方案:
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);
}
}
And just a small note : an explicit return
when not necessary is considered bad style in Rust. 请注意 :在Rust中,不必要时显式
return
是不好的样式。 Better stick to rule and write idiomatic code by removing return
whenever possible ;-) 通过尽可能地消除
return
更好地遵守规则并编写惯用代码;-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.