23
Reflection in Go [email protected]

Reflection in Go

Embed Size (px)

Citation preview

Reflection in Go

[email protected]

my Community contribution

Talking● Networking features● New 'net' in 1.8● Reflection● Channel Internals● Concurrency with

shared variables● Working with C code

and plugins

Doinggithub.com/golang/go/wiki/Projects

● Lxd

● Juju

● Go-merkle

● Etcd

● Epazote

● Go-kit

● Go-micro

● Prometheus

● llgo

outline

● What is Reflection● Reflection vs Introspection● 'reflect' package● Interesting issues● Packages using reflection

– Protocol encoding (gob)

– Encode-decode model (json, xml)

– template mechanisms

– Tracing

● Dealing uniformly with values of a type

Reflection

● the ability of a computer program to – examine and

– modify its own structure and behavior at runtime.

reflect package

● Provides the capability to reflect● Defines two important types

– Type

– Value

reflect.Type

● A Type represents a golang type.● It is an interface with multiple methods for

– distinguishing amongst types

– Inspecting the constituent components

● Type descriptors provide information about each type (it's name and methods)

type Type func ArrayOf(count int, elem Type) Type func ChanOf(dir ChanDir, t Type) Type func FuncOf(in, out []Type, variadic bool) Type func MapOf(key, elem Type) Type func PtrTo(t Type) Type func SliceOf(t Type) Type func StructOf(fields []StructField) Type func TypeOf(i interface{}) Type

var w io.Writerw = os.Stdoutw = new (bytes.Buffer)w = nil

?

reflect.Type

● reflect.TypeOf() accepts any interface{ } and returns its dynamic type as a reflect.Type

● Note: assignment from concrete value to interface type performs implicit interface conversion

type ChanDir func (d ChanDir) String() string type Kind func (k Kind) String() string type Method type SelectCase type SelectDir type SliceHeader type StringHeader type StructField type StructTag func (tag StructTag) Get(key string) string func (tag StructTag) Lookup(key string) (value string, ok bool)

reflect.Value

type Value func Append(s Value, x ...Value) Value func AppendSlice(s, t Value) Value func Indirect(v Value) Value func MakeChan(typ Type, buffer int) Value func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value func MakeMap(typ Type) Value func MakeSlice(typ Type, len, cap int) Value func New(typ Type) Value func NewAt(typ Type, p unsafe.Pointer) Value func ValueOf(i interface{}) Value func Zero(typ Type) Value

● reflect.Value can hold a value of any type.● reflect.ValueOf() accepts any interface{} and

returns a reflect.Value containing the interface's dynamic value (aka concrete value)

reflect.Value type Value ... func (v Value) Addr() Value func (v Value) Bool() bool func (v Value) Bytes() []byte func (v Value) Call(in []Value) []Value func (v Value) CallSlice(in []Value) []Value func (v Value) CanAddr() bool func (v Value) CanInterface() bool func (v Value) CanSet() bool func (v Value) Cap() int func (v Value) Close() func (v Value) Complex() complex128 func (v Value) Convert(t Type) Value func (v Value) Elem() Value func (v Value) Field(i int) Value func (v Value) FieldByIndex(index []int) Value func (v Value) FieldByName(name string) Value func (v Value) FieldByNameFunc(match func(string) bool) Value func (v Value) Float() float64 func (v Value) Index(i int) Value func (v Value) Int() int64 ...

reflect.Value type Value ... func (v Value) Interface() (i interface{}) func (v Value) InterfaceData() [2]uintptr func (v Value) IsNil() bool func (v Value) IsValid() bool func (v Value) Kind() Kind func (v Value) Len() int func (v Value) MapIndex(key Value) Value func (v Value) MapKeys() []Value func (v Value) Method(i int) Value func (v Value) MethodByName(name string) Value func (v Value) NumField() int func (v Value) NumMethod() int ... func (v Value) OverflowComplex(x complex128) bool func (v Value) OverflowFloat(x float64) bool func (v Value) OverflowInt(x int64) bool func (v Value) OverflowUint(x uint64) bool func (v Value) Pointer() uintptr func (v Value) Recv() (x Value, ok bool) func (v Value) Send(x Value)

reflect.Valuetype Value ... func (v Value) Set(x Value) func (v Value) SetBool(x bool) func (v Value) SetBytes(x []byte) func (v Value) SetCap(n int) func (v Value) SetComplex(x complex128) func (v Value) SetFloat(x float64) func (v Value) SetInt(x int64) func (v Value) SetLen(n int) func (v Value) SetMapIndex(key, val Value) func (v Value) SetPointer(x unsafe.Pointer) func (v Value) SetString(x string) func (v Value) SetUint(x uint64) func (v Value) Slice(i, j int) Value func (v Value) Slice3(i, j, k int) Value func (v Value) String() string func (v Value) TryRecv() (x Value, ok bool) func (v Value) TrySend(x Value) bool func (v Value) Type() Type func (v Value) Uint() uint64 func (v Value) UnsafeAddr() uintptr

example show_typepackage main

import ("fmt""reflect"

)

func main() {t := reflect.TypeOf (7)

fmt.Println (t)

fmt.Println (t.String())}

/* commentary TypeOf() call assigns the value 7 to the interface{} parameter. assignment from a concrete value to an interface type performs an implicit conversion which creates an interface value consisting of two components . dynamic type (int) . dynamic value (7)*/

cf: donovan

Example work with interfacepackage main

import ("fmt""reflect""os""io"

)

func main() {var w io.Writer = os.Stdout

fmt.Println (reflect.TypeOf(w))

}

/* commentary assignment from a concrete value to an interface type performs an implicit conversion which creates an interface value consisting of two components . dynamic type os.Stdout . dynamic value *os.File not io.Writer.*/

cf: donovan

Key insight● reflect.Type satisfies fmt.Stringer● fmt.Printf provides %T that uses reflect.TypeOf internally.

example set the value of a typepackage main

import ("fmt""reflect"

)

func main() {

x :=29

xref := reflect.ValueOf(&x).Elem()

px := xref.Addr().Interface().(*int)

*px = 7

fmt.Println(x)

xref.Set (reflect.ValueOf (99))

fmt.Println(x)}

code commentary/*commentary . create addressable value by &x . return inteface dynamic value reflect.ValueOf(&x) . Elem() returns the value that the interface v contains or that the pointer v points to.

It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil. . Addr() returns a value holding a pointer to the variable . Interface() returns interface{} value containing the pointer . use type assertion to retrieve the contents of the interface

direct

. use reflect.Value.Set()*/

Some interesting cases

#4876 https://github.com/golang/go/issues/4876– clarify behavior for unexported names

#5706 https://github.com/golang/go/issues/5706– field lookup ignores methods that cancel fields

(ambiguity is ignored)

– https://golang.org/src/reflect/type.go#L856

#12918 https://github.com/golang/go/issues/12918– DeepEqual returns false for equal slices

Encoding / Decoding

● Let's review go source code for– json code

– encoder

– decoder

● Performance comparison– easyjson

– ffjson

reflection

● Dealing uniformly with values of a type that– Do not have a common interface

– Do not have a known representation

– Do not exist at the time we design the function

● fmt.Fprintf

References {URL}

● S. Feferman (1962), Transfinite Recursions of Axiomatic Theories, Journal of Symbolic Logic, 27:259-316, 1962.

Conceptual Paper● Francois Nicola-Demers, Jacques Malenfant

(1995), Reflection in Logic, Functional and Object-Oriented programming https://www-master.ufr-info-p6.jussieu.fr/2007/Ajouts/Master_esj20_2007_2008/IMG/pdf/malenfant-ijcai95.pdf

Comparison with CLR model

● Reflection C++/CLI https://msdn.microsoft.com/en-us/library/y0114hz2.aspx

References {Golang centric}

● Golang 'reflect' package https://golang.org/pkg/reflect/

● The Laws of Reflection https://blog.golang.org/laws-of-reflection

● Russ Cox, Representation of interface values http://research.swtch.com/2009/12/go-data-structures-interfaces.html

● Phil Pearl, Anatomy of function call in Go https://syslog.ravelin.com/anatomy-of-a-function-call-in-go-f6fc81b80ecc#.cinqstkvx

References {json projects}

● easyjson https://github.com/mailru/easyjson

● ffjson https://github.com/pquerna/ffjson

● Go lang encoding https://github.com/golang/go/tree/master/src/encoding

Legal { Attribution(s) }

The usage of image is purely for illustrative purposes. The copyright of each image resides with their respective authors.