Skip to content

Commit e1b6464

Browse files
n
Change-Id: I1a5b0506d1f8a35e4a89ba9cf2700ab9be3ddfee
1 parent db63305 commit e1b6464

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
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.
2+
[Type.CanSeq] and [Type.CanSeq2] whether the report type can be use for range.
3+
[Value.Seq] and [Value.Seq2] similar for range a value.

src/reflect/all_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -8712,6 +8712,22 @@ func TestValueSeq(t *testing.T) {
87128712
}
87138713
}
87148714
}},
8715+
{"func", ValueOf(func(f func(int) bool) {
8716+
for i := range 4 {
8717+
f(i)
8718+
}
8719+
}), func(t *testing.T, s iter.Seq[Value]) {
8720+
i := int64(0)
8721+
for v := range s {
8722+
if v.Int() != i {
8723+
t.Fatalf("got %d, want %d", v.Int(), i)
8724+
}
8725+
i++
8726+
if i > 4 {
8727+
t.Fatalf("should loop four times")
8728+
}
8729+
}
8730+
}},
87158731
}
87168732
for _, tc := range tests {
87178733
seq := tc.val.Seq()
@@ -8808,6 +8824,25 @@ func TestValueSeq2(t *testing.T) {
88088824
}
88098825
}
88108826
}},
8827+
{"func", ValueOf(func(f func(int, int) bool) {
8828+
for i := range 4 {
8829+
f(i, i+1)
8830+
}
8831+
}), func(t *testing.T, s iter.Seq2[Value, Value]) {
8832+
i := int64(0)
8833+
for v1, v2 := range s {
8834+
if v1.Int() != i {
8835+
t.Fatalf("got %d, want %d", v1.Int(), i)
8836+
}
8837+
i++
8838+
if i > 4 {
8839+
t.Fatalf("should loop four times")
8840+
}
8841+
if v2.Int() != i {
8842+
t.Fatalf("got %d, want %d", v2.Int(), i)
8843+
}
8844+
}
8845+
}},
88118846
}
88128847
for _, tc := range tests {
88138848
seq := tc.val.Seq2()

src/reflect/type.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ type Type interface {
241241
// It panics if t's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
242242
OverflowUint(x uint64) bool
243243

244-
// CanSeq report whether the type is convertible to iter.Seq.
244+
// CanSeq whether the report type can be use for range one iteration variables.
245245
CanSeq() bool
246246

247-
// CanSeq2 report whether the type is convertible to iter.Seq2.
247+
// CanSeq2 whether the report type can be use for range two iteration variables.
248248
CanSeq2() bool
249249

250250
common() *abi.Type
@@ -873,10 +873,18 @@ func (t *rtype) OverflowUint(x uint64) bool {
873873
}
874874

875875
func (t *rtype) CanSeq() bool {
876-
return canSeq(&t.t)
876+
switch t.Kind() {
877+
case Int8, Int16, Int32, Int64, Int, Uint8, Uint16, Uint32, Uint64, Uint, Uintptr, Array, Slice, Chan, String, Map:
878+
return true
879+
case Func:
880+
return canRangeFunc(&t.t)
881+
case Pointer:
882+
return t.Elem().Kind() == Array
883+
}
884+
return false
877885
}
878886

879-
func canSeq(t *abi.Type) bool {
887+
func canRangeFunc(t *abi.Type) bool {
880888
if t.Kind() != abi.Func {
881889
return false
882890
}
@@ -893,10 +901,18 @@ func canSeq(t *abi.Type) bool {
893901
}
894902

895903
func (t *rtype) CanSeq2() bool {
896-
return canSeq2(&t.t)
904+
switch t.Kind() {
905+
case Array, Slice, String, Map:
906+
return true
907+
case Func:
908+
return canRangeFunc2(&t.t)
909+
case Pointer:
910+
return t.Elem().Kind() == Array
911+
}
912+
return false
897913
}
898914

899-
func canSeq2(t *abi.Type) bool {
915+
func canRangeFunc2(t *abi.Type) bool {
900916
if t.Kind() != abi.Func {
901917
return false
902918
}

src/reflect/type_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ func Test_Type_CanSeq(t *testing.T) {
126126
}{
127127
{"func(func(int) bool)", reflect.TypeOf(func(func(int) bool) {}), true},
128128
{"func(func(int))", reflect.TypeOf(func(func(int)) {}), false},
129+
{"int64", reflect.TypeOf(int64(1)), true},
130+
{"uint64", reflect.TypeOf(uint64(1)), true},
131+
{"*[4]int", reflect.TypeOf(&[4]int{}), true},
132+
{"chan int64", reflect.TypeOf(make(chan int64)), true},
133+
{"map[int]int", reflect.TypeOf(make(map[int]int)), true},
134+
{"string", reflect.TypeOf(""), true},
135+
{"[]int", reflect.TypeOf([]int{}), true},
129136
}
130137
for _, tt := range tests {
131138
t.Run(tt.name, func(t *testing.T) {
@@ -144,6 +151,13 @@ func Test_Type_CanSeq2(t *testing.T) {
144151
}{
145152
{"func(func(int, int) bool)", reflect.TypeOf(func(func(int, int) bool) {}), true},
146153
{"func(func(int, int))", reflect.TypeOf(func(func(int, int)) {}), false},
154+
{"int64", reflect.TypeOf(int64(1)), false},
155+
{"uint64", reflect.TypeOf(uint64(1)), false},
156+
{"*[4]int", reflect.TypeOf(&[4]int{}), true},
157+
{"chan int64", reflect.TypeOf(make(chan int64)), false},
158+
{"map[int]int", reflect.TypeOf(make(map[int]int)), true},
159+
{"string", reflect.TypeOf(""), true},
160+
{"[]int", reflect.TypeOf([]int{}), true},
147161
}
148162
for _, tt := range tests {
149163
t.Run(tt.name, func(t *testing.T) {

src/reflect/value.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3521,7 +3521,7 @@ func (v Value) Equal(u Value) bool {
35213521
// Otherwise v's kind must be Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
35223522
// Array, Chan, Map, Slice, or String.
35233523
func (v Value) Seq() iter.Seq[Value] {
3524-
if canSeq(v.typ()) {
3524+
if canRangeFunc(v.typ()) {
35253525
return func(yield func(Value) bool) {
35263526
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
35273527
return []Value{ValueOf(yield(in[0]))}
@@ -3589,7 +3589,7 @@ func (v Value) Seq() iter.Seq[Value] {
35893589

35903590
// Seq2 is like Seq but for two values.
35913591
func (v Value) Seq2() iter.Seq2[Value, Value] {
3592-
if canSeq2(v.typ()) {
3592+
if canRangeFunc2(v.typ()) {
35933593
return func(yield func(Value, Value) bool) {
35943594
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
35953595
return []Value{ValueOf(yield(in[0], in[1]))}

0 commit comments

Comments
 (0)