Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reflection in Go

A close look at Reflection in Go programming language.

  • Login to see the comments

Reflection in Go

  1. 1. Reflection in Go saifi@acm.org
  2. 2. my Community contribution Talking ● Networking features ● New 'net' in 1.8 ● Reflection ● Channel Internals ● Concurrency with shared variables ● Working with C code and plugins Doing github.com/golang/go/wiki/Projects ● Lxd ● Juju ● Go-merkle ● Etcd ● Epazote ● Go-kit ● Go-micro ● Prometheus ● llgo
  3. 3. 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
  4. 4. Reflection ● the ability of a computer program to – examine and – modify its own structure and behavior at runtime.
  5. 5. reflect package ● Provides the capability to reflect ● Defines two important types – Type – Value
  6. 6. 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.Writer w = os.Stdout w = new (bytes.Buffer) w = nil ?
  7. 7. 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)
  8. 8. 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)
  9. 9. 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 ...
  10. 10. 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)
  11. 11. reflect.Value type 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
  12. 12. example show_type package 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
  13. 13. Example work with interface package 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
  14. 14. Key insight ● reflect.Type satisfies fmt.Stringer ● fmt.Printf provides %T that uses reflect.TypeOf internally.
  15. 15. example set the value of a type package 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) }
  16. 16. 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() */
  17. 17. 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
  18. 18. Encoding / Decoding ● Let's review go source code for – json code – encoder – decoder – ● Performance comparison – easyjson – ffjson
  19. 19. 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
  20. 20. 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 Comparison with CLR model ● Reflection C++/CLI https://msdn.microsoft.com/en-us/libra
  21. 21. 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-structure ● Phil Pearl, Anatomy of function call in Go https://syslog.ravelin.com/anatomy-of-a-function-cal ●
  22. 22. 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/encodin ●
  23. 23. Legal { Attribution(s) } The usage of image is purely for illustrative purposes. The copyright of each image resides with their respective authors.

×