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 {
|
||||
// No Value types of private data can be constructed at the moment.
|
||||
return true
|
||||
return v.isExported()
|
||||
}
|
||||
|
||||
func (v Value) CanAddr() bool {
|
||||
|
@ -502,6 +501,9 @@ func (v Value) Index(i int) Value {
|
|||
// Extract a character from a string.
|
||||
// A string is never stored directly in the interface, but always as a
|
||||
// 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)
|
||||
if uint(i) >= uint(s.len) {
|
||||
panic("reflect: string index out of range")
|
||||
|
@ -509,6 +511,7 @@ func (v Value) Index(i int) Value {
|
|||
return Value{
|
||||
typecode: Uint8.basicType(),
|
||||
value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(uintptr(s.data) + uintptr(i))))),
|
||||
flags: v.flags & valueFlagExported,
|
||||
}
|
||||
case 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() {
|
||||
print(" addrable=true")
|
||||
}
|
||||
if !rv.CanInterface() {
|
||||
print(" caninterface=false")
|
||||
}
|
||||
if !rt.Comparable() {
|
||||
print(" comparable=false")
|
||||
}
|
||||
|
|
28
testdata/reflect.txt
предоставленный
28
testdata/reflect.txt
предоставленный
|
@ -236,7 +236,7 @@ reflect type: struct
|
|||
tag:
|
||||
embedded: true
|
||||
exported: false
|
||||
reflect type: interface
|
||||
reflect type: interface caninterface=false
|
||||
interface
|
||||
nil: true
|
||||
reflect type: struct
|
||||
|
@ -245,19 +245,19 @@ reflect type: struct
|
|||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: uint8
|
||||
reflect type: uint8 caninterface=false
|
||||
uint: 42
|
||||
field: 1 b
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: int16
|
||||
reflect type: int16 caninterface=false
|
||||
int: 321
|
||||
field: 2 c
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: int8
|
||||
reflect type: int8 caninterface=false
|
||||
int: 123
|
||||
reflect type: struct comparable=false
|
||||
struct: 5
|
||||
|
@ -265,45 +265,45 @@ reflect type: struct comparable=false
|
|||
tag: foo:"bar"
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: int
|
||||
reflect type: int caninterface=false
|
||||
int: 5
|
||||
field: 1 some
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: struct
|
||||
reflect type: struct caninterface=false
|
||||
struct: 2
|
||||
field: 0 X
|
||||
tag:
|
||||
embedded: false
|
||||
exported: true
|
||||
reflect type: int16
|
||||
reflect type: int16 caninterface=false
|
||||
int: -5
|
||||
field: 1 Y
|
||||
tag:
|
||||
embedded: false
|
||||
exported: true
|
||||
reflect type: int16
|
||||
reflect type: int16 caninterface=false
|
||||
int: 3
|
||||
field: 2 zero
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: struct
|
||||
reflect type: struct caninterface=false
|
||||
struct: 0
|
||||
field: 3 buf
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: slice comparable=false
|
||||
reflect type: slice caninterface=false comparable=false
|
||||
slice: uint8 2 2
|
||||
pointer: true
|
||||
nil: false
|
||||
indexing: 0
|
||||
reflect type: uint8 addrable=true
|
||||
reflect type: uint8 addrable=true caninterface=false
|
||||
uint: 71
|
||||
indexing: 1
|
||||
reflect type: uint8 addrable=true
|
||||
reflect type: uint8 addrable=true caninterface=false
|
||||
uint: 111
|
||||
field: 4 Buf
|
||||
tag:
|
||||
|
@ -325,14 +325,14 @@ reflect type: ptr
|
|||
tag: description:"chain"
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: ptr addrable=true
|
||||
reflect type: ptr addrable=true caninterface=false
|
||||
pointer: false struct
|
||||
nil: true
|
||||
field: 1 foo
|
||||
tag:
|
||||
embedded: false
|
||||
exported: false
|
||||
reflect type: int addrable=true
|
||||
reflect type: int addrable=true caninterface=false
|
||||
int: 42
|
||||
reflect type: slice comparable=false
|
||||
slice: interface 3 3
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче