Skip to content

Commit 8a67f56

Browse files
n
Change-Id: I5cdca1c39b82a9bfd9eb1b35009b9e4ec94ef346
1 parent 45059cf commit 8a67f56

File tree

5 files changed

+242
-25
lines changed

5 files changed

+242
-25
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The new method add a similar for range capability.
2+
[Type.CanSeq]/[Type.CanSeq2] report whether the type is convertible to [iter.Seq]/[iter.Seq2].
3+
[Value.Seq] and [Value.Seq2] Similar to reflection for range of a value.

src/go/build/deps_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ var depsRules = `
191191
192192
# FMT is OS (which includes string routines) plus reflect and fmt.
193193
# It does not include package log, which should be avoided in core packages.
194-
arena, strconv, unicode
194+
arena, strconv, unicode, iter
195195
< reflect;
196196
197197
os, reflect

src/iter/pull_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
//go:build goexperiment.rangefunc
66

7-
package iter
7+
package iter_test
88

99
import (
1010
"fmt"
11+
. "iter"
1112
"runtime"
1213
"testing"
1314
)

src/reflect/all_test.go

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"internal/goarch"
1515
"internal/testenv"
1616
"io"
17+
"iter"
1718
"math"
1819
"math/rand"
1920
"net"
@@ -8589,3 +8590,227 @@ func TestSliceAt(t *testing.T) {
85898590
// _ = SliceAt(typ, unsafe.Pointer(last), 1)
85908591
shouldPanic("", func() { _ = SliceAt(typ, unsafe.Pointer(last), 2) })
85918592
}
8593+
8594+
func TestValueSeq(t *testing.T) {
8595+
m := map[string]int{
8596+
"1": 1,
8597+
"2": 2,
8598+
"3": 3,
8599+
"4": 4,
8600+
}
8601+
c := make(chan int, 3)
8602+
for i := range 3 {
8603+
c <- i
8604+
}
8605+
tests := []struct {
8606+
name string
8607+
val Value
8608+
check func(*testing.T, iter.Seq[Value])
8609+
}{
8610+
{"int", ValueOf(4), func(t *testing.T, s iter.Seq[Value]) {
8611+
i := int64(0)
8612+
for v := range s {
8613+
if v.Int() != i {
8614+
t.Fatalf("got %d, want %d", v.Int(), i)
8615+
}
8616+
i++
8617+
if i > 4 {
8618+
t.Fatalf("should loop four times")
8619+
}
8620+
}
8621+
}},
8622+
{"uint", ValueOf(uint64(4)), func(t *testing.T, s iter.Seq[Value]) {
8623+
i := uint64(0)
8624+
for v := range s {
8625+
if v.Uint() != i {
8626+
t.Fatalf("got %d, want %d", v.Uint(), i)
8627+
}
8628+
i++
8629+
if i > 4 {
8630+
t.Fatalf("should loop four times")
8631+
}
8632+
}
8633+
}},
8634+
{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
8635+
i := int64(0)
8636+
for v := range s {
8637+
if v.Int() != i {
8638+
t.Fatalf("got %d, want %d", v.Int(), i)
8639+
}
8640+
i++
8641+
if i > 4 {
8642+
t.Fatalf("should loop four times")
8643+
}
8644+
}
8645+
}},
8646+
{"[4]int", ValueOf([4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
8647+
i := int64(0)
8648+
for v := range s {
8649+
if v.Int() != i {
8650+
t.Fatalf("got %d, want %d", v.Int(), i)
8651+
}
8652+
i++
8653+
if i > 4 {
8654+
t.Fatalf("should loop four times")
8655+
}
8656+
}
8657+
}},
8658+
{"[]int", ValueOf([]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
8659+
i := int64(0)
8660+
for v := range s {
8661+
if v.Int() != i {
8662+
t.Fatalf("got %d, want %d", v.Int(), i)
8663+
}
8664+
i++
8665+
if i > 4 {
8666+
t.Fatalf("should loop four times")
8667+
}
8668+
}
8669+
}},
8670+
{"string", ValueOf("1234"), func(t *testing.T, s iter.Seq[Value]) {
8671+
i := int64(0)
8672+
for v := range s {
8673+
if v.Int() != i {
8674+
t.Fatalf("got %d, want %d", v.Int(), i)
8675+
}
8676+
i++
8677+
if i > 4 {
8678+
t.Fatalf("should loop four times")
8679+
}
8680+
}
8681+
}},
8682+
{"map[string]int", ValueOf(m), func(t *testing.T, s iter.Seq[Value]) {
8683+
i := int64(0)
8684+
for v := range s {
8685+
if _, ok := m[v.String()]; !ok {
8686+
t.Fatalf("unexpected %v", v.Interface())
8687+
}
8688+
i++
8689+
if i > 4 {
8690+
t.Fatalf("should loop four times")
8691+
}
8692+
}
8693+
}},
8694+
{"chan int", ValueOf(c), func(t *testing.T, s iter.Seq[Value]) {
8695+
i := 0
8696+
m := map[int64]bool{
8697+
0: false,
8698+
1: false,
8699+
2: false,
8700+
}
8701+
for v := range s {
8702+
if b, ok := m[v.Int()]; !ok || b {
8703+
t.Fatalf("unexpected %v", v.Interface())
8704+
}
8705+
m[v.Int()] = true
8706+
i++
8707+
if i == 3 {
8708+
close(c)
8709+
}
8710+
if i > 3 {
8711+
t.Fatalf("should loop three times")
8712+
}
8713+
}
8714+
}},
8715+
}
8716+
for _, tc := range tests {
8717+
seq := tc.val.Seq()
8718+
tc.check(t, seq)
8719+
}
8720+
}
8721+
8722+
func TestValueSeq2(t *testing.T) {
8723+
m := map[string]int{
8724+
"1": 1,
8725+
"2": 2,
8726+
"3": 3,
8727+
"4": 4,
8728+
}
8729+
tests := []struct {
8730+
name string
8731+
val Value
8732+
check func(*testing.T, iter.Seq2[Value, Value])
8733+
}{
8734+
{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
8735+
i := int64(0)
8736+
for v1, v2 := range s {
8737+
if v1.Int() != i {
8738+
t.Fatalf("got %d, want %d", v1.Int(), i)
8739+
}
8740+
i++
8741+
if i > 4 {
8742+
t.Fatalf("should loop four times")
8743+
}
8744+
if v2.Int() != i {
8745+
t.Fatalf("got %d, want %d", v2.Int(), i)
8746+
}
8747+
}
8748+
}},
8749+
{"[4]int", ValueOf([4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
8750+
i := int64(0)
8751+
for v1, v2 := range s {
8752+
if v1.Int() != i {
8753+
t.Fatalf("got %d, want %d", v1.Int(), i)
8754+
}
8755+
i++
8756+
if i > 4 {
8757+
t.Fatalf("should loop four times")
8758+
}
8759+
if v2.Int() != i {
8760+
t.Fatalf("got %d, want %d", v2.Int(), i)
8761+
}
8762+
}
8763+
}},
8764+
{"[]int", ValueOf([]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
8765+
i := int64(0)
8766+
for v1, v2 := range s {
8767+
if v1.Int() != i {
8768+
t.Fatalf("got %d, want %d", v1.Int(), i)
8769+
}
8770+
i++
8771+
if i > 4 {
8772+
t.Fatalf("should loop four times")
8773+
}
8774+
if v2.Int() != i {
8775+
t.Fatalf("got %d, want %d", v2.Int(), i)
8776+
}
8777+
}
8778+
}},
8779+
{"string", ValueOf("1234"), func(t *testing.T, s iter.Seq2[Value, Value]) {
8780+
i := int64(0)
8781+
str := "1234"
8782+
for v1, v2 := range s {
8783+
if v1.Int() != i {
8784+
t.Fatalf("got %d, want %d", v1.Int(), i)
8785+
}
8786+
if v2.Interface() != str[i] {
8787+
t.Fatalf("got %v, want %v", v2.Interface(), str[i])
8788+
}
8789+
i++
8790+
if i > 4 {
8791+
t.Fatalf("should loop four times")
8792+
}
8793+
}
8794+
}},
8795+
{"map[string]int", ValueOf(m), func(t *testing.T, s iter.Seq2[Value, Value]) {
8796+
i := int64(0)
8797+
for v1, v2 := range s {
8798+
v, ok := m[v1.String()]
8799+
if !ok {
8800+
t.Fatalf("unexpected %v", v1.Interface())
8801+
}
8802+
if v != v2.Interface() {
8803+
t.Fatalf("got %v, want %v", v2.Interface(), m[v1.String()])
8804+
}
8805+
i++
8806+
if i > 4 {
8807+
t.Fatalf("should loop four times")
8808+
}
8809+
}
8810+
}},
8811+
}
8812+
for _, tc := range tests {
8813+
seq := tc.val.Seq2()
8814+
tc.check(t, seq)
8815+
}
8816+
}

src/reflect/value.go

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,18 +3551,17 @@ func (v Value) Seq() iter.Seq[Value] {
35513551
return nil
35523552
}
35533553
return func(yield func(Value) bool) {
3554-
len := v.Len()
35553554
v = v.Elem()
3556-
for i := range len {
3557-
if !yield(v.Index(i)) {
3555+
for i := range v.Len() {
3556+
if !yield(ValueOf(i)) {
35583557
return
35593558
}
35603559
}
35613560
}
3562-
case Slice, String:
3561+
case Array, Slice, String:
35633562
return func(yield func(Value) bool) {
35643563
for i := range v.Len() {
3565-
if !yield(v.Index(i)) {
3564+
if !yield(ValueOf(i)) {
35663565
return
35673566
}
35683567
}
@@ -3571,21 +3570,21 @@ func (v Value) Seq() iter.Seq[Value] {
35713570
return func(yield func(Value) bool) {
35723571
i := v.MapRange()
35733572
for i.Next() {
3574-
if !yield(i.Value()) {
3573+
if !yield(i.Key()) {
35753574
return
35763575
}
35773576
}
35783577
}
35793578
case Chan:
35803579
return func(yield func(Value) bool) {
3581-
for v, ok := v.Recv(); ok; {
3582-
if !yield(v) {
3580+
for value, ok := v.Recv(); ok; value, ok = v.Recv() {
3581+
if !yield(value) {
35833582
return
35843583
}
35853584
}
35863585
}
35873586
}
3588-
panic("reflect: " + v.Type().String() + " not make iter.Seq[Value]")
3587+
panic("reflect: " + v.Type().String() + " cannot produce iter.Seq[Value]")
35893588
}
35903589

35913590
// Seq2 is like Seq but for two values.
@@ -3599,22 +3598,19 @@ func (v Value) Seq2() iter.Seq2[Value, Value] {
35993598
}
36003599
}
36013600
switch v.Kind() {
3602-
case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3603-
panic("reflect: " + v.Type().String() + " not make iter.Seq2[Value, Value]")
36043601
case Pointer:
36053602
if !(v.Elem().kind() == Array) {
36063603
return nil
36073604
}
36083605
return func(yield func(Value, Value) bool) {
3609-
len := v.Len()
36103606
v = v.Elem()
3611-
for i := range len {
3607+
for i := range v.Len() {
36123608
if !yield(ValueOf(i), v.Index(i)) {
36133609
return
36143610
}
36153611
}
36163612
}
3617-
case Slice, String:
3613+
case Array, Slice, String:
36183614
return func(yield func(Value, Value) bool) {
36193615
for i := range v.Len() {
36203616
if !yield(ValueOf(i), v.Index(i)) {
@@ -3631,16 +3627,8 @@ func (v Value) Seq2() iter.Seq2[Value, Value] {
36313627
}
36323628
}
36333629
}
3634-
case Chan:
3635-
return func(yield func(Value, Value) bool) {
3636-
for v, ok := v.Recv(); ; {
3637-
if !yield(v, ValueOf(ok)) {
3638-
return
3639-
}
3640-
}
3641-
}
36423630
}
3643-
panic("reflect: " + v.Type().String() + " not make iter.Seq2[Value, Value]")
3631+
panic("reflect: " + v.Type().String() + " cannot produce iter.Seq2[Value, Value]")
36443632
}
36453633

36463634
// convertOp returns the function to convert a value of type src

0 commit comments

Comments
 (0)