iterator


Wrong number of lifetime parameters when using a modified `Chars` iterator


I want to implement the IntoIterator trait for a struct containing a String. The iterator is based on the chars() iterator, is supposed to count the '1' chars and accumulate the result. 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
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.
To answer the question you asked, I'd recommend to impl IntoIterator for &StringStruct (a reference to a StringStruct instead of the struct directly). 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.
The problem is that you try to name the type of your closure by writing 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").
This means that, right now, you can't specify the type of a Map<_, _> object. This is a known issue; the recently accepted impl Trait-RFC might offer a workaround for cases like this. 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<_, _>. Note that you can still use the Chars iterator. 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. Better stick to rule and write idiomatic code by removing return whenever possible ;-)

Related Links

Looping with iterator vs temp object gives different result graphically (Libgdx/Java)
Range over an arbitrary type
Iterating over keys/values of a std::vector and other containers in C++ (MWE)
Prolog Program to Find Square of Natural Numbers
specifying dynamic id while using <af:iterator and <af:selectbooleancheckobx
Any nicer way of iterating a number of times specified by an integer value?
Boost.Filesystem-like Library for D
What is most idiomatic way to create an iterator in Go?
How Iterator implement in TreeSet
Generator, enumerator, iterator definitions [closed]
How to refer to the iterator within the find_if predicate?
Is boost::filesystem::directory_iterator invalidated by deletion?
displaying item with an Iterator in ADF
pymongo - use a custom cursor class
Format an iterator in LabVIEW
Abstraction over container iterators

Categories

HOME
yii2
wso2
zeromq
oracle11g
tinymce
angular-material
electron
cplex
webstorm
youtube-dl
routes
jsp-tags
bookshelf.js
filtering
react-redux
paw-app
yum
wamp
floating-action-button
u-sql
circular-dependency
dtrace
flask-wtforms
quickfix
iron-router
opentracing
telephony
seaborn
tostring
database-replication
text-rendering
openedx
firefox-webextensions
karma-jasmine
swiftlint
autosys
facebook-access-token
ping
jspm
instant-messaging
google-rich-snippets
galsim
code-contracts
uiswipegesturerecognizer
xmlreader
form-data
geopositioning
rotational-matrices
sequential
appfabric
dartium
android-browser
objectlistview
reportbuilder
jna
pdf-reactor
reportingservices-2005
businessworks
cubic-spline
wso2carbon
fault
smartcontracts
apache-fop
revapi
multipeer-connectivity
rails-routing
slickedit
webdriverjs
cubes
parallel-data-warehouse
abcpdf9
gridpane
ctest
fputcsv
rvest
lib.web.mvc
teamcity-8.0
wireshark-dissector
asp.net-dynamic-data
applescript-objc
websocket4net
android-radiobutton
system.net.webexception
xceed-datagrid
picturefill
farseer
xsockets.net
jsctypes
tidy
dotnetnuke-5
eclipse-memory-analyzer
pygit2
typoscript2
pvrtc
sublist
funscript
manchester-syntax
regsvr32
nsmanagedobject
removeclass
work-stealing
xmemcached
floating
xfbml
gallio
filtered-index
firefox-5
fixed-width
nintendo-ds
sector
private-members
rtml

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App