mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 11:07:46 +00:00
reflect: add limited support for all type kinds
This commit makes sure all Go types can be encoded in the interface type code, so that Type.Kind() always returns a proper type kind for any non-nil interface.
This commit is contained in:
Vendored
+80
-1
@@ -5,16 +5,29 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type myint int
|
||||
type (
|
||||
myint int
|
||||
myslice []byte
|
||||
myslice2 []myint
|
||||
)
|
||||
|
||||
func main() {
|
||||
println("matching types")
|
||||
println(reflect.TypeOf(int(3)) == reflect.TypeOf(int(5)))
|
||||
println(reflect.TypeOf(int(3)) == reflect.TypeOf(uint(5)))
|
||||
println(reflect.TypeOf(myint(3)) == reflect.TypeOf(int(5)))
|
||||
println(reflect.TypeOf(myslice{}) == reflect.TypeOf([]byte{}))
|
||||
println(reflect.TypeOf(myslice2{}) == reflect.TypeOf([]myint{}))
|
||||
println(reflect.TypeOf(myslice2{}) == reflect.TypeOf([]int{}))
|
||||
|
||||
println("\nvalues of interfaces")
|
||||
var zeroSlice []byte
|
||||
var zeroFunc func()
|
||||
var zeroMap map[string]int
|
||||
var zeroChan chan int
|
||||
n := 42
|
||||
for _, v := range []interface{}{
|
||||
// basic types
|
||||
true,
|
||||
false,
|
||||
int(2000),
|
||||
@@ -37,15 +50,57 @@ func main() {
|
||||
float64(3.14),
|
||||
complex64(1.2 + 0.3i),
|
||||
complex128(1.3 + 0.4i),
|
||||
myint(32),
|
||||
"foo",
|
||||
unsafe.Pointer(new(int)),
|
||||
// channels
|
||||
zeroChan,
|
||||
// pointers
|
||||
new(int),
|
||||
new(error),
|
||||
&n,
|
||||
// slices
|
||||
[]byte{1, 2, 3},
|
||||
make([]uint8, 2, 5),
|
||||
[]rune{3, 5},
|
||||
[]string{"xyz", "Z"},
|
||||
zeroSlice,
|
||||
[]byte{},
|
||||
// array
|
||||
[4]int{1, 2, 3, 4},
|
||||
// functions
|
||||
zeroFunc,
|
||||
emptyFunc,
|
||||
// maps
|
||||
zeroMap,
|
||||
map[string]int{},
|
||||
// structs
|
||||
struct{}{},
|
||||
struct{ error }{},
|
||||
} {
|
||||
showValue(v, "")
|
||||
}
|
||||
|
||||
// test sizes
|
||||
println("\nsizes:")
|
||||
println("int8", int(reflect.TypeOf(int8(0)).Size()))
|
||||
println("int16", int(reflect.TypeOf(int16(0)).Size()))
|
||||
println("int32", int(reflect.TypeOf(int32(0)).Size()))
|
||||
println("int64", int(reflect.TypeOf(int64(0)).Size()))
|
||||
println("uint8", int(reflect.TypeOf(uint8(0)).Size()))
|
||||
println("uint16", int(reflect.TypeOf(uint16(0)).Size()))
|
||||
println("uint32", int(reflect.TypeOf(uint32(0)).Size()))
|
||||
println("uint64", int(reflect.TypeOf(uint64(0)).Size()))
|
||||
println("float32", int(reflect.TypeOf(float32(0)).Size()))
|
||||
println("float64", int(reflect.TypeOf(float64(0)).Size()))
|
||||
println("complex64", int(reflect.TypeOf(complex64(0)).Size()))
|
||||
println("complex128", int(reflect.TypeOf(complex128(0)).Size()))
|
||||
assertSize(reflect.TypeOf(uintptr(0)).Size() == unsafe.Sizeof(uintptr(0)), "uintptr")
|
||||
assertSize(reflect.TypeOf("").Size() == unsafe.Sizeof(""), "string")
|
||||
assertSize(reflect.TypeOf(new(int)).Size() == unsafe.Sizeof(new(int)), "*int")
|
||||
}
|
||||
|
||||
func emptyFunc() {
|
||||
}
|
||||
|
||||
func showValue(v interface{}, indent string) {
|
||||
@@ -79,13 +134,37 @@ func showValue(v interface{}, indent string) {
|
||||
}
|
||||
case reflect.UnsafePointer:
|
||||
println(indent+" pointer:", rv.Pointer() != 0)
|
||||
case reflect.Array:
|
||||
println(indent + " array")
|
||||
case reflect.Chan:
|
||||
println(indent+" chan:", rt.Elem().Kind().String())
|
||||
println(indent+" nil:", rv.IsNil())
|
||||
case reflect.Func:
|
||||
println(indent + " func")
|
||||
println(indent+" nil:", rv.IsNil())
|
||||
case reflect.Map:
|
||||
println(indent + " map")
|
||||
println(indent+" nil:", rv.IsNil())
|
||||
case reflect.Ptr:
|
||||
println(indent+" pointer:", rv.Pointer() != 0, rt.Elem().Kind().String())
|
||||
println(indent+" nil:", rv.IsNil())
|
||||
case reflect.Slice:
|
||||
println(indent+" slice:", rt.Elem().Kind().String(), rv.Len(), rv.Cap())
|
||||
println(indent+" pointer:", rv.Pointer() != 0)
|
||||
println(indent+" nil:", rv.IsNil())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
println(indent+" indexing:", i)
|
||||
showValue(rv.Index(i).Interface(), indent+" ")
|
||||
}
|
||||
case reflect.Struct:
|
||||
println(indent + " struct")
|
||||
default:
|
||||
println(indent + " unknown type kind!")
|
||||
}
|
||||
}
|
||||
|
||||
func assertSize(ok bool, typ string) {
|
||||
if !ok {
|
||||
panic("size mismatch for type " + typ)
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+65
@@ -2,6 +2,9 @@ matching types
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
|
||||
values of interfaces
|
||||
reflect type: bool
|
||||
@@ -48,6 +51,8 @@ reflect type: complex64
|
||||
complex: (+1.200000e+000+3.000000e-001i)
|
||||
reflect type: complex128
|
||||
complex: (+1.300000e+000+4.000000e-001i)
|
||||
reflect type: int
|
||||
int: 32
|
||||
reflect type: string
|
||||
string: foo 3
|
||||
reflect type: uint8
|
||||
@@ -58,8 +63,22 @@ reflect type: string
|
||||
uint: 111
|
||||
reflect type: unsafe.Pointer
|
||||
pointer: true
|
||||
reflect type: chan
|
||||
chan: int
|
||||
nil: true
|
||||
reflect type: ptr
|
||||
pointer: true int
|
||||
nil: false
|
||||
reflect type: ptr
|
||||
pointer: true interface
|
||||
nil: false
|
||||
reflect type: ptr
|
||||
pointer: true int
|
||||
nil: false
|
||||
reflect type: slice
|
||||
slice: uint8 3 3
|
||||
pointer: true
|
||||
nil: false
|
||||
indexing: 0
|
||||
reflect type: uint8
|
||||
uint: 1
|
||||
@@ -71,6 +90,8 @@ reflect type: slice
|
||||
uint: 3
|
||||
reflect type: slice
|
||||
slice: uint8 2 5
|
||||
pointer: true
|
||||
nil: false
|
||||
indexing: 0
|
||||
reflect type: uint8
|
||||
uint: 0
|
||||
@@ -79,6 +100,8 @@ reflect type: slice
|
||||
uint: 0
|
||||
reflect type: slice
|
||||
slice: int32 2 2
|
||||
pointer: true
|
||||
nil: false
|
||||
indexing: 0
|
||||
reflect type: int32
|
||||
int: 3
|
||||
@@ -87,6 +110,8 @@ reflect type: slice
|
||||
int: 5
|
||||
reflect type: slice
|
||||
slice: string 2 2
|
||||
pointer: true
|
||||
nil: false
|
||||
indexing: 0
|
||||
reflect type: string
|
||||
string: xyz 3
|
||||
@@ -101,3 +126,43 @@ reflect type: slice
|
||||
string: Z 1
|
||||
reflect type: uint8
|
||||
uint: 90
|
||||
reflect type: slice
|
||||
slice: uint8 0 0
|
||||
pointer: false
|
||||
nil: true
|
||||
reflect type: slice
|
||||
slice: uint8 0 0
|
||||
pointer: true
|
||||
nil: false
|
||||
reflect type: array
|
||||
array
|
||||
reflect type: func
|
||||
func
|
||||
nil: true
|
||||
reflect type: func
|
||||
func
|
||||
nil: false
|
||||
reflect type: map
|
||||
map
|
||||
nil: true
|
||||
reflect type: map
|
||||
map
|
||||
nil: false
|
||||
reflect type: struct
|
||||
struct
|
||||
reflect type: struct
|
||||
struct
|
||||
|
||||
sizes:
|
||||
int8 1
|
||||
int16 2
|
||||
int32 4
|
||||
int64 8
|
||||
uint8 1
|
||||
uint16 2
|
||||
uint32 4
|
||||
uint64 8
|
||||
float32 4
|
||||
float64 8
|
||||
complex64 8
|
||||
complex128 16
|
||||
|
||||
Reference in New Issue
Block a user