88 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
| // +build ignore
 | |
| 
 | |
| package main
 | |
| 
 | |
| import "reflect"
 | |
| import "unsafe"
 | |
| 
 | |
| var a, b int
 | |
| var unknown bool
 | |
| 
 | |
| func reflectIndirect() {
 | |
| 	ptr := &a
 | |
| 	// Pointer:
 | |
| 	print(reflect.Indirect(reflect.ValueOf(&ptr)).Interface().(*int)) // @pointsto main.a
 | |
| 	// Non-pointer:
 | |
| 	print(reflect.Indirect(reflect.ValueOf([]*int{ptr})).Interface().([]*int)[0]) // @pointsto main.a
 | |
| }
 | |
| 
 | |
| func reflectNewAt() {
 | |
| 	var x [8]byte
 | |
| 	print(reflect.NewAt(reflect.TypeOf(3), unsafe.Pointer(&x)).Interface()) // @types *int
 | |
| }
 | |
| 
 | |
| // @warning "unsound: main.reflectNewAt contains a reflect.NewAt.. call"
 | |
| 
 | |
| func reflectTypeOf() {
 | |
| 	t := reflect.TypeOf(3)
 | |
| 	if unknown {
 | |
| 		t = reflect.TypeOf("foo")
 | |
| 	}
 | |
| 	// TODO(adonovan): make types.Eval let us refer to unexported types.
 | |
| 	print(t)                             // #@types *reflect.rtype
 | |
| 	print(reflect.Zero(t).Interface())   // @types int | string
 | |
| 	newint := reflect.New(t).Interface() // @line rtonew
 | |
| 	print(newint)                        // @types *int | *string
 | |
| 	print(newint.(*int))                 // @pointsto <alloc in reflect.New>
 | |
| 	print(newint.(*string))              // @pointsto <alloc in reflect.New>
 | |
| }
 | |
| 
 | |
| func reflectTypeElem() {
 | |
| 	print(reflect.Zero(reflect.TypeOf(&a).Elem()).Interface())                       // @types int
 | |
| 	print(reflect.Zero(reflect.TypeOf([]string{}).Elem()).Interface())               // @types string
 | |
| 	print(reflect.Zero(reflect.TypeOf(make(chan bool)).Elem()).Interface())          // @types bool
 | |
| 	print(reflect.Zero(reflect.TypeOf(make(map[string]float64)).Elem()).Interface()) // @types float64
 | |
| 	print(reflect.Zero(reflect.TypeOf([3]complex64{}).Elem()).Interface())           // @types complex64
 | |
| 	print(reflect.Zero(reflect.TypeOf(3).Elem()).Interface())                        // @types
 | |
| 	print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()))                     // @types interface{}
 | |
| 	print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()).Interface())         // @types
 | |
| }
 | |
| 
 | |
| // reflect.Values within reflect.Values.
 | |
| func metareflection() {
 | |
| 	// "box" a *int twice, unbox it twice.
 | |
| 	v0 := reflect.ValueOf(&a)
 | |
| 	print(v0)                              // @types *int
 | |
| 	v1 := reflect.ValueOf(v0)              // box
 | |
| 	print(v1)                              // @types reflect.Value
 | |
| 	v2 := reflect.ValueOf(v1)              // box
 | |
| 	print(v2)                              // @types reflect.Value
 | |
| 	v1a := v2.Interface().(reflect.Value)  // unbox
 | |
| 	print(v1a)                             // @types reflect.Value
 | |
| 	v0a := v1a.Interface().(reflect.Value) // unbox
 | |
| 	print(v0a)                             // @types *int
 | |
| 	print(v0a.Interface().(*int))          // @pointsto main.a
 | |
| 
 | |
| 	// "box" an interface{} lvalue twice, unbox it twice.
 | |
| 	var iface interface{} = 3
 | |
| 	x0 := reflect.ValueOf(&iface).Elem()
 | |
| 	print(x0)                              // @types interface{}
 | |
| 	x1 := reflect.ValueOf(x0)              // box
 | |
| 	print(x1)                              // @types reflect.Value
 | |
| 	x2 := reflect.ValueOf(x1)              // box
 | |
| 	print(x2)                              // @types reflect.Value
 | |
| 	x1a := x2.Interface().(reflect.Value)  // unbox
 | |
| 	print(x1a)                             // @types reflect.Value
 | |
| 	x0a := x1a.Interface().(reflect.Value) // unbox
 | |
| 	print(x0a)                             // @types interface{}
 | |
| 	print(x0a.Interface())                 // @types int
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	reflectIndirect()
 | |
| 	reflectNewAt()
 | |
| 	reflectTypeOf()
 | |
| 	reflectTypeElem()
 | |
| 	metareflection()
 | |
| }
 |