Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Iterator
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==In different programming languages== ===.NET=== Iterators in the [[.NET Framework]] (i.e. C#) are called "enumerators" and represented by the <code>IEnumerator</code> interface.<ref name=Albahari>{{cite book |last=Albahari |first=Joseph |title= C# 10 in a Nutshell |date=2022 |publisher= O'Reilly |isbn= 978-1-098-12195-2}}</ref>{{rp|189β190, 344}}<ref name=Skeet>{{cite book |last=Skeet|first=Jon|title= C# in Depth |date=23 March 2019 |publisher= Manning |isbn= 978-1617294532}}</ref>{{rp|53β54}}<code>IEnumerator</code> provides a <code>MoveNext()</code> method, which advances to the next element and indicates whether the end of the collection has been reached;<ref name=Albahari/>{{rp|344}}<ref name=Skeet/>{{rp|55β56}}<ref name=Price>{{cite book |last=Price | first=Mark J. |title=C# 8.0 and .NET Core 3.0 β Modern Cross-Platform Development: Build Applications with C#, .NET Core, Entity Framework Core, ASP.NET Core, and ML.NET Using Visual Studio Code | publisher= Packt |isbn= 978-1-098-12195-2}}</ref>{{rp|89}} a <code>Current</code> property, to obtain the value of the element currently being pointed at.<ref name=Albahari/>{{rp|344}}<ref name=Skeet/>{{rp|56}}<ref name=Price/>{{rp|89}} and an optional <code>Reset()</code> method,<ref name=Albahari/>{{rp|344}} to rewind the enumerator back to its initial position. The enumerator initially points to a special value before the first element, so a call to <code>MoveNext()</code> is required to begin iterating. Enumerators are typically obtained by calling the <code>GetEnumerator()</code> method of an object implementing the <code>IEnumerable</code> interface.<ref name=Skeet/>{{rp|54β56}}<ref name=Price/>{{rp|54β56}} a <code>Current</code> property, to obtain the value of the element currently being pointed at;<ref name=Albahari/>{{rp|344}}<ref name=Skeet/>{{rp|56}}<ref name=Price/>{{rp|89}}Container classes typically implement this interface. However, the [[foreach]] statement in [[C Sharp (programming language)|C#]] can operate on any object providing such a method, even if it does not implement <code>IEnumerable</code> ([[duck typing]]).<ref name=Price/>{{rp|89}} Both interfaces were expanded into [[generic programming|generic]] versions in [[.NET Framework#.NET Framework 2.0|.NET 2.0]]. The following shows a simple use of iterators in C# 2.0: <syntaxhighlight lang="csharp"> // explicit version IEnumerator<MyType> iter = list.GetEnumerator(); while (iter.MoveNext()) Console.WriteLine(iter.Current); // implicit version foreach (MyType value in list) Console.WriteLine(value); </syntaxhighlight> C# 2.0 also supports [[#Generators|generators]]: a method that is declared as returning <code>IEnumerator</code> (or <code>IEnumerable</code>), but uses the "<code>yield return</code>" statement to produce a sequence of elements instead of returning an object instance, will be transformed by the compiler into a new class implementing the appropriate interface. ===C++=== The [[C++]] language makes wide use of iterators in its [[C++ Standard Library|Standard Library]] and describes several categories of iterators differing in the repertoire of operations they allow. These include ''forward iterators'', ''bidirectional iterators'', and ''random access iterators'', in order of increasing possibilities. All of the standard container template types provide iterators of one of these categories. Iterators generalize pointers to elements of an array (which indeed can be used as iterators), and their syntax is designed to resemble that of [[C (programming language)|C]] [[pointer arithmetic]], where the <code>*</code> and <code>-></code> operators are used to reference the element to which the iterator points and pointer arithmetic operators like <code>++</code> are used to modify iterators in the traversal of a container. Traversal using iterators usually involves a single varying iterator, and two fixed iterators that serve to delimit a range to be traversed. The distance between the limiting iterators, in terms of the number of applications of the operator <code>++</code> needed to transform the lower limit into the upper one, equals the number of items in the designated range; the number of distinct iterator values involved is one more than that. By convention, the lower limiting iterator "points to" the first element in the range, while the upper limiting iterator does not point to any element in the range, but rather just beyond the end of the range. For traversal of an entire container, the <code>begin()</code> method provides the lower limit, and <code>end()</code> the upper limit. The latter does not reference any element of the container at all but is a valid iterator value that can be compared against. The following example shows a typical use of an iterator. <syntaxhighlight lang="cpp"> std::vector<int> items; items.push_back(5); // Append integer value '5' to vector 'items'. items.push_back(2); // Append integer value '2' to vector 'items'. items.push_back(9); // Append integer value '9' to vector 'items'. for (auto it = items.begin(), end = items.end(); it != end; ++it) { // Iterate through 'items'. std::cout << *it; // And print value of 'items' for current index. } // In C++11, the same can be done without using any iterators: for (auto x : items) { std::cout << x; // Print value of each element 'x' of 'items'. } // Both of the for loops print "529". </syntaxhighlight> Iterator types are separate from the container types they are used with, though the two are often used in concert. The category of the iterator (and thus the operations defined for it) usually depends on the type of container, with for instance arrays or vectors providing random access iterators, but sets (which use a linked structure as implementation) only providing bidirectional iterators. One same container type can have more than one associated iterator type; for instance the <code>std::vector<T></code> container type allows traversal either using (raw) pointers to its elements (of type <code>*<T></code>), or values of a special type <code>std::vector<T>::iterator</code>, and yet another type is provided for "reverse iterators", whose operations are defined in such a way that an algorithm performing a usual (forward) traversal will actually do traversal in reverse order when called with reverse iterators. Most containers also provide a separate <code>const_iterator</code> type, for which operations that would allow changing the values pointed to are intentionally not defined. Simple traversal of a container object or a range of its elements (including modification of those elements unless a <code>const_iterator</code> is used) can be done using iterators alone. But container types may also provide methods like <code>insert</code> or <code>erase</code> that modify the structure of the container itself; these are methods of the container class, but in addition require one or more iterator values to specify the desired operation. While it is possible to have multiple iterators pointing into the same container simultaneously, structure-modifying operations may invalidate certain iterator values (the standard specifies for each case whether this may be so); using an invalidated iterator is an error that will lead to undefined behavior, and such errors need not be signaled by the run time system. Implicit iteration is also partially supported by C++ through the use of standard function templates, such as <code>[https://en.cppreference.com/w/cpp/algorithm/for_each std::for_each()]</code>, <code>[https://en.cppreference.com/w/cpp/algorithm/copy std::copy()]</code> and <code>[https://en.cppreference.com/w/cpp/algorithm/accumulate std::accumulate()]</code>. When used they must be initialized with existing iterators, usually <code>begin</code> and <code>end</code>, that define the range over which iteration occurs. But no explicit iterator object is subsequently exposed as the iteration proceeds. This example shows the use of <code>for_each</code>. <syntaxhighlight lang="cpp"> ContainerType<ItemType> c; // Any standard container type of ItemType elements. void ProcessItem(const ItemType& i) { // Function that will process each item of the collection. std::cout << i << std::endl; } std::for_each(c.begin(), c.end(), ProcessItem); // A for-each iteration loop. </syntaxhighlight> The same can be achieved using <code>std::copy</code>, passing a <code>[https://en.cppreference.com/w/cpp/iterator/ostream_iterator std::ostream_iterator]</code> value as third iterator: <syntaxhighlight lang="cpp"> std::copy(c.begin(), c.end(), std::ostream_iterator<ItemType>(std::cout, "\n")); </syntaxhighlight> Since [[C++11]], [[C++11#Lambda functions and expressions|lambda function]] syntax can be used to specify to operation to be iterated inline, avoiding the need to define a named function. Here is an example of for-each iteration using a lambda function: <syntaxhighlight lang="cpp"> ContainerType<ItemType> c; // Any standard container type of ItemType elements. // A for-each iteration loop with a lambda function. std::for_each(c.begin(), c.end(), [](const ItemType& i) { std::cout << i << std::endl; }); </syntaxhighlight> ===Java=== Introduced in the [[Java (programming language)|Java]] JDK 1.2 release, the {{Javadoc:SE|package=java.util|java/util|Iterator}} interface allows the iteration of container classes. Each <code>Iterator</code> provides a {{Javadoc:SE|name=next()|java/util|Iterator|next()}} and {{Javadoc:SE|name=hasNext()|java/util|Iterator|hasNext()}} method,<ref name=Bloch>{{cite book | title= "Effective Java: Programming Language Guide" |last=Bloch| first=Joshua| publisher=Addison-Wesley | edition=third | isbn=978-0134685991| year=2018}}</ref>{{rp|294β295}} and may optionally support a {{Javadoc:SE|name=remove()|java/util|Iterator|remove()}}<ref name=Bloch/>{{rp|262, 266}} method. Iterators are created by the corresponding container class, typically by a method named <code>iterator()</code>.<ref>{{cite web | url = http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Iterator.html | title = java.util: Interface Iterator<E>: Method Summary | publisher = Oracle | access-date = 2012-08-08 }}</ref><ref name=Bloch/>{{rp|99}}<ref name=Bloch/>{{rp|217}} The <code>next()</code> method advances the iterator and returns the value pointed to by the iterator. The first element is obtained upon the first call to <code>next()</code>.<ref name=Bloch/>{{rp|294β295}} To determine when all the elements in the container have been visited the <code>hasNext()</code> test method is used.<ref name=Bloch/>{{rp|262}} The following example shows a simple use of iterators: <syntaxhighlight lang="java"> Iterator iter = list.iterator(); // Iterator<MyType> iter = list.iterator(); // in J2SE 5.0 while (iter.hasNext()) { System.out.print(iter.next()); if (iter.hasNext()) System.out.print(", "); } </syntaxhighlight> To show that <code>hasNext()</code> can be called repeatedly, we use it to insert commas between the elements but not after the last element. This approach does not properly separate the advance operation from the actual data access. If the data element must be used more than once for each advance, it needs to be stored in a temporary variable. When an advance is needed without data access (i.e. to skip a given data element), the access is nonetheless performed, though the returned value is ignored in this case. For collection types that support it, the <code>remove()</code> method of the iterator removes the most recently visited element from the container while keeping the iterator usable. Adding or removing elements by calling the methods of the container (also from the same [[Thread (computer science)|thread]]) makes the iterator unusable. An attempt to get the next element throws the exception. An exception is also thrown if there are no more elements remaining (<code>hasNext()</code> has previously returned false). Additionally, for {{Javadoc:SE|package=java.util|java/util|List}} there is a {{Javadoc:SE|package=java.util|java/util|ListIterator}} with a similar API but that allows forward and backward iteration, provides its current index in the list and allows setting of the list element at its position. The [[Java Platform, Standard Edition|J2SE]] 5.0 release of Java introduced the {{Javadoc:SE|java/lang|Iterable}} interface to support an enhanced <code>for</code> ([[foreach]]) loop for iterating over collections and arrays. <code>Iterable</code> defines the {{Javadoc:SE|name=iterator()|java/lang|Iterable|iterator()}} method that returns an <code>Iterator</code>.<ref name=Bloch/>{{rp|266}} Using the enhanced <code>for</code> loop, the preceding example can be rewritten as <syntaxhighlight lang="java"> for (MyType obj : list) { System.out.print(obj); } </syntaxhighlight> Some containers also use the older (since 1.0) <code>Enumeration</code> class. It provides <code>hasMoreElements()</code> and <code>nextElement()</code> methods but has no methods to modify the container. === Scala === In [[Scala (programming language)|Scala]], iterators have a rich set of methods similar to collections, and can be used directly in for loops. Indeed, both iterators and collections inherit from a common base trait - <code>scala.collection.TraversableOnce</code>. However, because of the rich set of methods available in the Scala collections library, such as <code>map</code>, <code>collect</code>, <code>filter</code> etc., it is often not necessary to deal with iterators directly when programming in Scala. Java iterators and collections can be automatically converted into Scala iterators and collections, respectively, simply by adding the single line <syntaxhighlight lang="scala"> import scala.collection.JavaConversions._ </syntaxhighlight> to the file. The <code>JavaConversions</code> object provides implicit conversions to do this. Implicit conversions are a feature of Scala: methods that, when visible in the current scope, automatically insert calls to themselves into relevant expressions at the appropriate place to make them typecheck when they otherwise would not. === MATLAB === [[MATLAB]] supports both external and internal implicit iteration using either "native" arrays or <code>cell</code> arrays. In the case of external iteration where the onus is on the user to advance the traversal and request next elements, one can define a set of elements within an array storage structure and traverse the elements using the <code>for</code>-loop construct. For example, <syntaxhighlight lang="matlab"> % Define an array of integers myArray = [1,3,5,7,11,13]; for n = myArray % ... do something with n disp(n) % Echo integer to Command Window end </syntaxhighlight> traverses an array of integers using the <code>for</code> keyword. In the case of internal iteration where the user can supply an operation to the iterator to perform over every element of a collection, many built-in operators and MATLAB functions are overloaded to execute over every element of an array and return a corresponding output array implicitly. Furthermore, the <code>arrayfun</code> and <code>cellfun</code> functions can be leveraged for performing custom or user defined operations over "native" arrays and <code>cell</code> arrays respectively. For example, <syntaxhighlight lang="matlab"> function simpleFun % Define an array of integers myArray = [1,3,5,7,11,13]; % Perform a custom operation over each element myNewArray = arrayfun(@(a)myCustomFun(a),myArray); % Echo resulting array to Command Window myNewArray function outScalar = myCustomFun(inScalar) % Simply multiply by 2 outScalar = 2*inScalar; </syntaxhighlight> defines a primary function <code>simpleFun</code> that implicitly applies custom subfunction <code>myCustomFun</code> to each element of an array using built-in function <code>arrayfun</code>. Alternatively, it may be desirable to abstract the mechanisms of the array storage container from the user by defining a custom object-oriented MATLAB implementation of the Iterator Pattern. Such an implementation supporting external iteration is demonstrated in MATLAB Central File Exchange item [http://www.mathworks.com.au/matlabcentral/fileexchange/25225 Design Pattern: Iterator (Behavioral)]. This is written in the new class-definition syntax introduced with MATLAB software version 7.6 (R2008a) and features a one-dimensional <code>cell</code> array realization of the [[List (computing)|List Abstract Data Type]] (ADT) as the mechanism for storing a heterogeneous (in data type) set of elements. It provides the functionality for explicit forward [[List (computing)|List]] traversal with the <code>hasNext()</code>, <code>next()</code> and <code>reset()</code> methods for use in a <code>while</code>-loop. === PHP === [[File:UML PHP iterator interface.svg|right|UML class diagram of the Iterator interface in PHP]] [[PHP]]'s [[foreach loop|<code>foreach</code> loop]] was introduced in version 4.0 and made compatible with objects as values in 4.0 Beta 4.<ref>{{cite web | url = https://secure.php.net/ChangeLog-4.php#4.0b4 | title = PHP 4 ChangeLog | access-date = 2015-10-13 | date = 2000-02-20 | publisher = The PHP Group }}</ref> However, support for iterators was added in PHP 5 through the introduction of the internal<ref>Internal refers to the fact that the interface cannot be implemented in PHP scripts, only in the [[C (programming language)]] source.</ref> <code>Traversable</code> interface.<ref>{{cite web | url = https://secure.php.net/class.traversable | title = The Traversable interface | access-date = 2015-10-13 | publisher = The PHP Group }}</ref> The two main interfaces for implementation in PHP scripts that enable objects to be iterated via the <code>foreach</code> loop are <code>Iterator</code> and <code>IteratorAggregate</code>. The latter does not require the implementing class to declare all required methods, instead it implements an [[Mutator method|accessor]] method (<code>getIterator</code>) that returns an instance of <code>Traversable</code>. The [[Standard PHP Library]] provides several classes to work with special iterators.<ref>{{cite web | url = https://secure.php.net/spl.iterators | title = Iterators | access-date = 2015-10-13 | publisher = The PHP Group }}</ref> PHP also supports [[Generator (computer programming)|Generators]] since 5.5.<ref>{{cite web | url = https://secure.php.net/ChangeLog-5.php#5.5.0 | title = PHP 5 ChangeLog | access-date = 2015-10-13 | date = 2013-06-20 | publisher = The PHP Group }}</ref> The simplest implementation is by wrapping an array, this can be useful for [[PHP#TYPE-HINTING|type hinting]] and [[information hiding]]. <syntaxhighlight lang="php"> namespace Wikipedia\Iterator; final class ArrayIterator extends \Iterator { private array $array; public function __construct(array $array) { $this->array = $array; } public function rewind(): void { echo 'rewinding' , PHP_EOL; reset($this->array); } public function current() { $value = current($this->array); echo "current: {$value}", PHP_EOL; return $value; } public function key() { $key = key($this->array); echo "key: {$key}", PHP_EOL; return $key; } public function next() { $value = next($this->array); echo "next: {$value}", PHP_EOL; return $value; } public function valid(): bool { $valid = $this->current() !== false; echo 'valid: ', ($valid ? 'true' : 'false'), PHP_EOL; return $valid; } } </syntaxhighlight> All methods of the example class are used during the execution of a complete foreach loop (<code>foreach ($iterator as $key => $current) {}</code>). The iterator's methods are executed in the following order: # <code>$iterator->rewind()</code> ensures that the internal structure starts from the beginning. # <code>$iterator->valid()</code> returns ''true'' in this example. # <code>$iterator->current()</code> returned value is stored in <code>$value</code>. # <code>$iterator->key()</code> returned value is stored in <code>$key</code>. # <code>$iterator->next()</code> advances to the next element in the internal structure. # <code>$iterator->valid()</code> returns ''false'' and the loop is aborted. The next example illustrates a PHP class that implements the <code>Traversable</code> interface, which could be wrapped in an <code>IteratorIterator</code> class to act upon the data before it is returned to the <code>foreach</code> loop. The usage together with the <code>MYSQLI_USE_RESULT</code> constant allows PHP scripts to iterate result sets with billions of rows with very little memory usage. These features are not exclusive to PHP nor to its MySQL class implementations (e.g. the <code>PDOStatement</code> class implements the <code>Traversable</code> interface as well). <syntaxhighlight lang="php"> mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $mysqli = new \mysqli('host.example.com', 'username', 'password', 'database_name'); // The \mysqli_result class that is returned by the method call implements the internal Traversable interface. foreach ($mysqli->query('SELECT `a`, `b`, `c` FROM `table`', MYSQLI_USE_RESULT) as $row) { // Act on the returned row, which is an associative array. } </syntaxhighlight> ===Python===<!-- This section is linked from [[Associative array]] --> Iterators in [[Python (programming language)|Python]] are a fundamental part of the language and in many cases go unseen as they are implicitly used in the <code>for</code> ([[foreach]]) statement, in [[list comprehension]]s, and in [[Python syntax and semantics#Generator expressions|generator expressions]]. All of Python's standard built-in [[Collection (abstract data type)|collection]] types support iteration, as well as many classes that are part of the standard library. The following example shows typical implicit iteration over a sequence: <syntaxhighlight lang="python"> for value in sequence: print(value) </syntaxhighlight> Python dictionaries (a form of [[associative array]]) can also be directly iterated over, when the dictionary keys are returned; or the <code>items()</code> method of a dictionary can be iterated over where it yields corresponding key,value pairs as a tuple: <syntaxhighlight lang="python"> for key in dictionary: value = dictionary[key] print(key, value) </syntaxhighlight> <syntaxhighlight lang="python"> for key, value in dictionary.items(): print(key, value) </syntaxhighlight> Iterators however can be used and defined explicitly. For any iterable sequence type or class, the built-in function <code>iter()</code> is used to create an iterator object. The iterator object can then be iterated with the <code>next()</code> function, which uses the <code>__next__()</code> method internally, which returns the next element in the container. (The previous statement applies to Python 3.x. In Python 2.x, the <code>next()</code> method is equivalent.) A <code>StopIteration</code> exception will be raised when no more elements are left. The following example shows an equivalent iteration over a sequence using explicit iterators: <syntaxhighlight lang="python"> it = iter(sequence) while True: try: value = it.next() # in Python 2.x value = next(it) # in Python 3.x except StopIteration: break print(value) </syntaxhighlight> Any user-defined class can support standard iteration (either implicit or explicit) by defining an <code>__iter__()</code> method that returns an iterator object. The iterator object then needs to define a <code>__next__()</code> method that returns the next element. Python's [[#Generators|generators]] implement this iteration [[Protocol (object-oriented programming)|protocol]]. ===Raku=== Iterators in [[Raku (programming language)|Raku]] are a fundamental part of the language, although usually users do not have to care about iterators. Their usage is hidden behind iteration APIs such as the <code>for</code> statement, <code>map</code>, <code>grep</code>, list indexing with <code>.[$idx]</code>, etc. The following example shows typical implicit iteration over a collection of values: <syntaxhighlight lang="raku"> my @values = 1, 2, 3; for @values -> $value { say $value } # OUTPUT: # 1 # 2 # 3 </syntaxhighlight> Raku hashes can also be directly iterated over; this yields key-value <code>Pair</code> objects. The <code>kv</code> method can be invoked on the hash to iterate over the key and values; the <code>keys</code> method to iterate over the hash's keys; and the <code>values</code> method to iterate over the hash's values. <syntaxhighlight lang="raku"> my %word-to-number = 'one' => 1, 'two' => 2, 'three' => 3; for %word-to-number -> $pair { say $pair; } # OUTPUT: # three => 3 # one => 1 # two => 2 for %word-to-number.kv -> $key, $value { say "$key: $value" } # OUTPUT: # three: 3 # one: 1 # two: 2 for %word-to-number.keys -> $key { say "$key => " ~ %word-to-number{$key}; } # OUTPUT: # three => 3 # one => 1 # two => 2 </syntaxhighlight> Iterators however can be used and defined explicitly. For any iterable type, there are several methods that control different aspects of the iteration process. For example, the <code>iterator</code> method is supposed to return an <code>Iterator</code> object, and the <code>pull-one</code> method is supposed to produce and return the next value if possible, or return the sentinel value <code>IterationEnd</code> if no more values could be produced. The following example shows an equivalent iteration over a collection using explicit iterators: <syntaxhighlight lang="raku"> my @values = 1, 2, 3; my $it := @values.iterator; # grab iterator for @values loop { my $value := $it.pull-one; # grab iteration's next value last if $value =:= IterationEnd; # stop if we reached iteration's end say $value; } # OUTPUT: # 1 # 2 # 3 </syntaxhighlight> All iterable types in Raku compose the <code>Iterable</code> role, <code>Iterator</code> role, or both. The <code>Iterable</code> is quite simple and only requires the <code>iterator</code> to be implemented by the composing class. The <code>Iterator</code> is more complex and provides a series of methods such as <code>pull-one</code>, which allows for a finer operation of iteration in several contexts such as adding or eliminating items, or skipping over them to access other items. Thus, any user-defined class can support standard iteration by composing these roles and implementing the <code>iterator</code> and/or <code>pull-one</code> methods. The <code>DNA</code> class represents a DNA strand and implements the <code>iterator</code> by composing the <code>Iterable</code> role. The DNA strand is split into a group of trinucleotides when iterated over: <syntaxhighlight lang="raku"> subset Strand of Str where { .match(/^^ <[ACGT]>+ $$/) and .chars %% 3 }; class DNA does Iterable { has $.chain; method new(Strand:D $chain) { self.bless: :$chain } method iterator(DNA:D:){ $.chain.comb.rotor(3).iterator } }; for DNA.new('GATTACATA') { .say } # OUTPUT: # (G A T) # (T A C) # (A T A) say DNA.new('GATTACATA').map(*.join).join('-'); # OUTPUT: # GAT-TAC-ATA </syntaxhighlight> The <code>Repeater</code> class composes both the <code>Iterable</code> and <code>Iterator</code> roles: <syntaxhighlight lang="raku"> class Repeater does Iterable does Iterator { has Any $.item is required; has Int $.times is required; has Int $!count = 1; multi method new($item, $times) { self.bless: :$item, :$times; } method iterator { self } method pull-one(--> Mu){ if $!count <= $!times { $!count += 1; return $!item } else { return IterationEnd } } } for Repeater.new("Hello", 3) { .say } # OUTPUT: # Hello # Hello # Hello </syntaxhighlight> ===Ruby=== Ruby implements iterators quite differently; all iterations are done by means of passing callback closures to container methods - this way Ruby not only implements basic iteration but also several patterns of iteration like function mapping, filters and reducing. Ruby also supports an alternative syntax for the basic iterating method <code>each</code>, the following three examples are equivalent: <syntaxhighlight lang="ruby"> (0...42).each do |n| puts n end </syntaxhighlight> ...and... <syntaxhighlight lang="ruby"> for n in 0...42 puts n end </syntaxhighlight> or even shorter <syntaxhighlight lang="ruby"> 42.times do |n| puts n end </syntaxhighlight> Ruby can also iterate over fixed lists by using <code>Enumerator</code>s and either calling their <code>#next</code> method or doing a for each on them, as above. ===Rust=== Rust makes use of external iterators throughout the standard library, including in its <code>for</code> loop, which implicitly calls the <code>next()</code> method of an iterator until it is consumed. The most basic <code>for</code> loop for example iterates over a <code>Range</code> type: <syntaxhighlight lang="rust"> for i in 0..42 { println!("{}", i); } // Prints the numbers 0 to 41 </syntaxhighlight> Specifically, the <code>for</code> loop will call a value's <code>into_iter()</code> method, which returns an iterator that in turn yields the elements to the loop. The <code>for</code> loop (or indeed, any method that consumes the iterator), proceeds until the <code>next()</code> method returns a <code>None</code> value (iterations yielding elements return a <code>Some(T)</code> value, where <code>T</code> is the element type). All collections provided by the standard library implement the <code>IntoIterator</code> trait (meaning they define the <code>into_iter()</code> method). Iterators themselves implement the <code>Iterator</code> trait, which requires defining the <code>next()</code> method. Furthermore, any type implementing <code>Iterator</code> is automatically provided an implementation for <code>IntoIterator</code> that returns itself. Iterators support various adapters (<code>map()</code>, <code>filter()</code>, <code>skip()</code>, <code>take()</code>, etc.) as methods provided automatically by the <code>Iterator</code> trait. Users can create custom iterators by creating a type implementing the <code>Iterator</code> trait. Custom collections can implement the <code>IntoIterator</code> trait and return an associated iterator type for their elements, enabling their use directly in <code>for</code> loops. Below, the <code>Fibonacci</code> type implements a custom, unbounded iterator: <syntaxhighlight lang="rust"> struct Fibonacci(u64, u64); impl Fibonacci { pub fn new() -> Self { Self(0, 1) } } impl Iterator for Fibonacci { type Item = u64; fn next(&mut self) -> Option<Self::Item> { let next = self.0; self.0 = self.1; self.1 = self.0 + next; Some(next) } } let fib = Fibonacci::new(); for n in fib.skip(1).step_by(2).take(4) { println!("{n}"); } // Prints 1, 2, 5, and 13 </syntaxhighlight> [[File:UML class diagram Rust iterators.svg|UML class diagram depecting the iterator-related structs and traits in Rust]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)