]> Cypherpunks repositories - gostls13.git/commitdiff
spec: document for range loop over functions
authorRobert Griesemer <gri@golang.org>
Thu, 30 May 2024 23:49:21 +0000 (16:49 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 4 Jun 2024 15:28:33 +0000 (15:28 +0000)
For #61405.
Fixes #65237.

Change-Id: Ia7820c0ef089c828ea7ed3d2802c5185c945290e
Reviewed-on: https://go-review.googlesource.com/c/go/+/589397
TryBot-Bypass: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
doc/go_spec.html

index 277cd277758d6c75ac0f6228ba25f4198bdf470b..748fcc1ba02cbd740f2e0f2ef6142897af991972 100644 (file)
@@ -1,6 +1,6 @@
 <!--{
        "Title": "The Go Programming Language Specification",
-       "Subtitle": "Language version go1.22 (April 25, 2024)",
+       "Subtitle": "Language version go1.23 (June 4, 2024)",
        "Path": "/ref/spec"
 }-->
 
@@ -6656,13 +6656,16 @@ if the respective iteration variables are present:
 </p>
 
 <pre class="grammar">
-Range expression                                   1st value                2nd value
+Range expression                                       1st value                2nd value
 
-array or slice  a  [n]E, *[n]E, or []E             index    i  int          a[i]       E
-string          s  string type                     index    i  int          see below  rune
-map             m  map[K]V                         key      k  K            m[k]       V
-channel         c  chan E, &lt;-chan E                element  e  E
-integer value   n  integer type, or untyped int    value    i  see below
+array or slice      a  [n]E, *[n]E, or []E             index    i  int          a[i]       E
+string              s  string type                     index    i  int          see below  rune
+map                 m  map[K]V                         key      k  K            m[k]       V
+channel             c  chan E, &lt;-chan E                element  e  E
+integer value       n  integer type, or untyped int    value    i  see below
+function, 0 values  f  func(func() bool)
+function, 1 value   f  func(func(V) bool)              value    v  V
+function, 2 values  f  func(func(K, V) bool)           key      k  K            v          V
 </pre>
 
 <ol>
@@ -6716,6 +6719,23 @@ Otherwise, if the iteration variable is declared by the "range" clause or is abs
 the type of the iteration values is the <a href="#Constants">default type</a> for <code>n</code>.
 If <code>n</code> &lt= 0, the loop does not run any iterations.
 </li>
+
+<li>
+For a function <code>f</code>, the iteration proceeds by calling <code>f</code>
+with a new, synthesized <code>yield</code> function as its argument.
+If <code>yield</code> is called before <code>f</code> returns,
+the arguments to <code>yield</code> become the iteration values
+for executing the loop body once.
+After each successive loop iteration, <code>yield</code> returns true
+and may be called again to continue the loop.
+As long as the loop body does not terminate, the "range" clause will continue
+to generate iteration values this way for each <code>yield</code> call until
+<code>f</code> returns.
+If the loop body terminates (such as by a <code>break</code> statement),
+<code>yield</code> returns false and must not be called again.
+The number of iteration variables must match the number and order of arguments
+to <code>yield</code>.
+</li>
 </ol>
 
 <p>
@@ -6784,6 +6804,16 @@ for u = range 256 {
 // invalid: 1e3 is a floating-point constant
 for range 1e3 {
 }
+<!-- TODO(gri) need better examples for range-over-func -->
+// print hello world
+f := func(yield func(string) bool) {
+       if yield("hello") {
+               yield("world")
+       }
+}
+for word := range f {
+       println(word)
+}
 </pre>