reflect: implement CanInterface and fix string Index()
This commit fixes two related issues: 1. CanInterface was unimplemented. It now uses the same check as is used in Interface() itself. This issue led to https://github.com/tinygo-org/tinygo/issues/3033 2. Allow making an interface out of a string char element. Doing this in one commit (instead of two) because they are shown to be correct with the same tests.
Этот коммит содержится в:
родитель
edaf13f951
коммит
e955aa1941
3 изменённых файлов: 22 добавлений и 16 удалений
|
@ -168,8 +168,7 @@ func (v Value) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) CanInterface() bool {
|
func (v Value) CanInterface() bool {
|
||||||
// No Value types of private data can be constructed at the moment.
|
return v.isExported()
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) CanAddr() bool {
|
func (v Value) CanAddr() bool {
|
||||||
|
@ -502,6 +501,9 @@ func (v Value) Index(i int) Value {
|
||||||
// Extract a character from a string.
|
// Extract a character from a string.
|
||||||
// A string is never stored directly in the interface, but always as a
|
// A string is never stored directly in the interface, but always as a
|
||||||
// pointer to the string value.
|
// pointer to the string value.
|
||||||
|
// Keeping valueFlagExported if set, but don't set valueFlagIndirect
|
||||||
|
// otherwise CanSet will return true for string elements (which is bad,
|
||||||
|
// strings are read-only).
|
||||||
s := *(*stringHeader)(v.value)
|
s := *(*stringHeader)(v.value)
|
||||||
if uint(i) >= uint(s.len) {
|
if uint(i) >= uint(s.len) {
|
||||||
panic("reflect: string index out of range")
|
panic("reflect: string index out of range")
|
||||||
|
@ -509,6 +511,7 @@ func (v Value) Index(i int) Value {
|
||||||
return Value{
|
return Value{
|
||||||
typecode: Uint8.basicType(),
|
typecode: Uint8.basicType(),
|
||||||
value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(uintptr(s.data) + uintptr(i))))),
|
value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(uintptr(s.data) + uintptr(i))))),
|
||||||
|
flags: v.flags & valueFlagExported,
|
||||||
}
|
}
|
||||||
case Array:
|
case Array:
|
||||||
// Extract an element from the array.
|
// Extract an element from the array.
|
||||||
|
|
3
testdata/reflect.go
предоставленный
3
testdata/reflect.go
предоставленный
|
@ -415,6 +415,9 @@ func showValue(rv reflect.Value, indent string) {
|
||||||
if rv.CanAddr() {
|
if rv.CanAddr() {
|
||||||
print(" addrable=true")
|
print(" addrable=true")
|
||||||
}
|
}
|
||||||
|
if !rv.CanInterface() {
|
||||||
|
print(" caninterface=false")
|
||||||
|
}
|
||||||
if !rt.Comparable() {
|
if !rt.Comparable() {
|
||||||
print(" comparable=false")
|
print(" comparable=false")
|
||||||
}
|
}
|
||||||
|
|
28
testdata/reflect.txt
предоставленный
28
testdata/reflect.txt
предоставленный
|
@ -236,7 +236,7 @@ reflect type: struct
|
||||||
tag:
|
tag:
|
||||||
embedded: true
|
embedded: true
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: interface
|
reflect type: interface caninterface=false
|
||||||
interface
|
interface
|
||||||
nil: true
|
nil: true
|
||||||
reflect type: struct
|
reflect type: struct
|
||||||
|
@ -245,19 +245,19 @@ reflect type: struct
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: uint8
|
reflect type: uint8 caninterface=false
|
||||||
uint: 42
|
uint: 42
|
||||||
field: 1 b
|
field: 1 b
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: int16
|
reflect type: int16 caninterface=false
|
||||||
int: 321
|
int: 321
|
||||||
field: 2 c
|
field: 2 c
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: int8
|
reflect type: int8 caninterface=false
|
||||||
int: 123
|
int: 123
|
||||||
reflect type: struct comparable=false
|
reflect type: struct comparable=false
|
||||||
struct: 5
|
struct: 5
|
||||||
|
@ -265,45 +265,45 @@ reflect type: struct comparable=false
|
||||||
tag: foo:"bar"
|
tag: foo:"bar"
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: int
|
reflect type: int caninterface=false
|
||||||
int: 5
|
int: 5
|
||||||
field: 1 some
|
field: 1 some
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: struct
|
reflect type: struct caninterface=false
|
||||||
struct: 2
|
struct: 2
|
||||||
field: 0 X
|
field: 0 X
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: true
|
exported: true
|
||||||
reflect type: int16
|
reflect type: int16 caninterface=false
|
||||||
int: -5
|
int: -5
|
||||||
field: 1 Y
|
field: 1 Y
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: true
|
exported: true
|
||||||
reflect type: int16
|
reflect type: int16 caninterface=false
|
||||||
int: 3
|
int: 3
|
||||||
field: 2 zero
|
field: 2 zero
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: struct
|
reflect type: struct caninterface=false
|
||||||
struct: 0
|
struct: 0
|
||||||
field: 3 buf
|
field: 3 buf
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: slice comparable=false
|
reflect type: slice caninterface=false comparable=false
|
||||||
slice: uint8 2 2
|
slice: uint8 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
indexing: 0
|
indexing: 0
|
||||||
reflect type: uint8 addrable=true
|
reflect type: uint8 addrable=true caninterface=false
|
||||||
uint: 71
|
uint: 71
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: uint8 addrable=true
|
reflect type: uint8 addrable=true caninterface=false
|
||||||
uint: 111
|
uint: 111
|
||||||
field: 4 Buf
|
field: 4 Buf
|
||||||
tag:
|
tag:
|
||||||
|
@ -325,14 +325,14 @@ reflect type: ptr
|
||||||
tag: description:"chain"
|
tag: description:"chain"
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: ptr addrable=true
|
reflect type: ptr addrable=true caninterface=false
|
||||||
pointer: false struct
|
pointer: false struct
|
||||||
nil: true
|
nil: true
|
||||||
field: 1 foo
|
field: 1 foo
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
exported: false
|
exported: false
|
||||||
reflect type: int addrable=true
|
reflect type: int addrable=true caninterface=false
|
||||||
int: 42
|
int: 42
|
||||||
reflect type: slice comparable=false
|
reflect type: slice comparable=false
|
||||||
slice: interface 3 3
|
slice: interface 3 3
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче