Skip to content

Commit 535f81e

Browse files
griesemergopherbot
authored andcommitted
spec: document for range loop over functions
For #61405. Fixes #65237. Change-Id: Ia7820c0ef089c828ea7ed3d2802c5185c945290e Reviewed-on: https://go-review.googlesource.com/c/go/+/589397 TryBot-Bypass: Robert Griesemer <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 200b280 commit 535f81e

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

doc/go_spec.html

+37-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--{
22
"Title": "The Go Programming Language Specification",
3-
"Subtitle": "Language version go1.22 (April 25, 2024)",
3+
"Subtitle": "Language version go1.23 (June 4, 2024)",
44
"Path": "/ref/spec"
55
}-->
66

@@ -6656,13 +6656,16 @@ <h4 id="For_range">For statements with <code>range</code> clause</h4>
66566656
</p>
66576657

66586658
<pre class="grammar">
6659-
Range expression 1st value 2nd value
6659+
Range expression 1st value 2nd value
66606660

6661-
array or slice a [n]E, *[n]E, or []E index i int a[i] E
6662-
string s string type index i int see below rune
6663-
map m map[K]V key k K m[k] V
6664-
channel c chan E, &lt;-chan E element e E
6665-
integer value n integer type, or untyped int value i see below
6661+
array or slice a [n]E, *[n]E, or []E index i int a[i] E
6662+
string s string type index i int see below rune
6663+
map m map[K]V key k K m[k] V
6664+
channel c chan E, &lt;-chan E element e E
6665+
integer value n integer type, or untyped int value i see below
6666+
function, 0 values f func(func() bool)
6667+
function, 1 value f func(func(V) bool) value v V
6668+
function, 2 values f func(func(K, V) bool) key k K v V
66666669
</pre>
66676670

66686671
<ol>
@@ -6716,6 +6719,23 @@ <h4 id="For_range">For statements with <code>range</code> clause</h4>
67166719
the type of the iteration values is the <a href="#Constants">default type</a> for <code>n</code>.
67176720
If <code>n</code> &lt= 0, the loop does not run any iterations.
67186721
</li>
6722+
6723+
<li>
6724+
For a function <code>f</code>, the iteration proceeds by calling <code>f</code>
6725+
with a new, synthesized <code>yield</code> function as its argument.
6726+
If <code>yield</code> is called before <code>f</code> returns,
6727+
the arguments to <code>yield</code> become the iteration values
6728+
for executing the loop body once.
6729+
After each successive loop iteration, <code>yield</code> returns true
6730+
and may be called again to continue the loop.
6731+
As long as the loop body does not terminate, the "range" clause will continue
6732+
to generate iteration values this way for each <code>yield</code> call until
6733+
<code>f</code> returns.
6734+
If the loop body terminates (such as by a <code>break</code> statement),
6735+
<code>yield</code> returns false and must not be called again.
6736+
The number of iteration variables must match the number and order of arguments
6737+
to <code>yield</code>.
6738+
</li>
67196739
</ol>
67206740

67216741
<p>
@@ -6784,6 +6804,16 @@ <h4 id="For_range">For statements with <code>range</code> clause</h4>
67846804
// invalid: 1e3 is a floating-point constant
67856805
for range 1e3 {
67866806
}
6807+
<!-- TODO(gri) need better examples for range-over-func -->
6808+
// print hello world
6809+
f := func(yield func(string) bool) {
6810+
if yield("hello") {
6811+
yield("world")
6812+
}
6813+
}
6814+
for word := range f {
6815+
println(word)
6816+
}
67876817
</pre>
67886818

67896819

0 commit comments

Comments
 (0)