Access a Field#

Go code:

Object.Field

Equivalent reflect code:

Given an object with a field of a known name, use Value.FieldByName

obj := reflect.ValueOf(Object)
field := obj.FieldByName("Field")

If Field were the 2nd field on obj, this would be equivalent:

field := obj.Field(1)

Value.Field will panic if there is no nth field, so use Value.NumField to make sure that

n < obj.NumField()

There is also a Value.FieldByIndex, which takes a slice of int's. For each int in the slice, it calls Field on, first, the reflect.Value it was invoked on, and after that on the result of the last invocation of Field. So

obj.Field(1)

is equivalent to

obj.Field([]int{1})

and

obj.Field([]int{1, 2, 3})

is equivalent to

obj.Field(1).Field(2).Field(3)

FieldByIndex is primarily useful if you are keeping analysis of a type separate from manipulation of values of that type. This is common, for example, in serialization code that builds a table of what to serialize given a type and then given a value looks the type up in a table and processes the entry using the already computed recipe.

Address#

Go code:

v := &value

Equivalent reflect code:

Given a variable value of type reflect.Value.

v := value.Addr()

Value.Addr will panic if value is not addressable. To check, use Value.CanAddr

if value.CanAddr() {
	v = value.Addr()
}

Append#

Append to a slice.

Go code:

slice = append(slice, 1, 2)

Equivalent reflect code:

a := reflect.ValueOf(1)
b := reflect.ValueOf(2)
slice = reflect.Append(slice, a, b)

Append a slice to a slice#

The ... operator won't work on a reflected slice. Rather than iterating over the indices and appending them one at a time you can use reflect.AppendSlice.

Go code:

slice = append(slice, slice2...)

Equivalent reflect code:

slice = reflect.AppendSlice(slice, slice2)

Assignment#

Go code:

a = b

Equivalent reflect code:

For a, b of reflect.Value

a.Set(b)

To make sure this operation won't panic, use Value.CanSet

if a.CanSet() {
	a.Set(b)
}

In addition to the generic Value.Set there are a number of type specific helper methods on Value for primitive types and byte slices. Make sure that the type of a is the appropriate type before calling.

//bool
a.SetBool(true)
//byte slice
a.SetBytes([]byte{})
//string
a.SetString("π≈3.1415")

For the numeric types int, uint, float64, complex64, byte, int8, int16, etc, there are methods on reflect.Value—Value.SetComplex, Value.SetFloat, Value.SetInt, Value.SetUint— to set the largest of each category of numeric types; namely, int64, uint64, float64, and complex128.

a.SetComplex(1.3+2i)
a.SetFloat(3.14)
a.SetInt(-1)
a.SetUint(0)

If the reflect.Value isn't an int64, uint64, float64, or complex128, it's possible that the value being assigned will not fit. For example, assigning 65 000 to an int8.

To handle this possibility there are Value.OverlfowComplex, Value.OverflowFloat, Value.OverflowInt, and Value.OverflowUint. In the following assume that b is an arbitrary value of the appropriate type

if a.CanSet() && !a.OverflowComplex(b) {
	a.SetComplex(b)
}
if a.CanSet() && !a.OverflowFloat(b) {
	a.SetFloat(b)
}
if a.CanSet() && !a.OverflowInt(b) {
	a.SetInt(b)
}
if a.CanSet() && !a.OverflowUint(b) {
	a.SetUint(b)
}

Asynchronous Communication#

Value.TryRecv and Value.TrySend are not technically in the language.

Value.TryRecv was in the language previous to Go 1, using the v, ok = <-c syntax.

It was removed in favor of letting the ok denote whether the channel is closed.

Until Go 1.1, these were used to make up for a lack of there being a way to select on channels. However, even now that you can select with reflect, Value.TryRecv and Value.TrySend are still useful given how awkward doing selects are in reflect.

Go code:

ok := false
select {
case v := <-c:
	ok = true
default:
}
ok := false
select {
case c <- v:
	ok = true
default:
}

Equivalent reflect code:

v, ok := c.TryRecv()
ok := c.TrySend(v)

Capacity#

Use Value.Cap to get the capacity of an array, slice, or chan.

Go code:

cp := cap(v)

Equivalent reflect code:

cp := v.Cap()

Close a channel#

Go code:

close(c)

Equivalent reflect code:

c.Close() //where c is a reflect.Value of a channel

Copy#

Copying an array or slice.

Go code:

n := copy(dst, src)

Equivalent reflect code:

n := reflect.Copy(dst, src)

Creating simple composite types#

Go code:

Given a type T, creating a slice of T, a pointer to T, or a map to T (with some key type K), creating an unnamed type is simple enough.

type slice  []T
type ptr    *T
type bichan chan T
type rchan  <-chan T
type schan  chan<-T
type a_map  map[K]T

Equivalent reflect code:

With reflected types, unless you happen to have both a reflect.Value (or reflect.Type) for T and []T (or *T or chan T)—or K and T and map[K]T—you have to create the type with one of the following:

slice  := reflect.SliceOf(T)
ptr    := reflect.PtrTo(T)
bichan := reflect.ChanOf(reflect.BothDir, T)
rchan  := reflect.ChanOf(reflect.RecvDir, T)
schan  := reflect.ChanOf(reflect.SendDir, T)
a_map  := reflect.MapOf(K, T)

Indexing#

Go code:

v := indexable[index]
indexable[index] = v

Equivalent reflect code:

Arrays and Slices are fairly similar and only require Value.Index

//For an array or slice
v := indexable.Index(index)
indexable.Index(index).Set(v)

Maps require Value.MapIndex and Value.SetMapIndex

//For a map
v := indexable.MapIndex(index)
indexable.SetMapIndex(index, value)

Indirect#

Go code:

v := *pointer

Equivalent reflect code:

There are two ways: reflect.Indirect and Value.Elem. reflect.Indirect only operates on pointers whereas Value.Elem works on pointers or interfaces.

Reflect.Indirect:

v := reflect.Indirect(pointer)

Note: if pointer is nil, rather than panicing, reflect.Indirect will return the zero value of the appropriate type.

Use Value.IsNil to check that pointer is not nil before indirection.

if !pointer.IsNil() {
	v = reflect.Indirect(pointer)
}

Value.Elem:

v := pointer.Elem()

Like reflect.Indirect, Value.Elem returns the zero value if pointer is nil.

if !pointer.IsNil() {
	v = pointer.Elem()
}

Invoke a function#

Go code:

NoArgumentsOrReturns() //func()
one, two := TwoParamsTwoReturns("hi", 0) //func(string, int) (int, error)
ex := VariadicFunc("θ", 1, 2, 3) //func(string, ...int) bool

Equivalent reflect code:

There are two ways to invoke a function: Value.Call and Value.CallSlice. The latter is only for variadic functions; however, somewhat confusingly, both work with variadic functions in exactly the same way: only use Value.CallSlice if, for some reason, the function you wish to call MUST be variadic.

Both take and return a slice of reflect.Value.

Each of the parameters must be assignable to the respective argument.

For variadic functions, the variadic parameters are just the parameters in the slice after the required parameters. So, if you were calling

func VariadicFunc(a string, more ...int)

the parameter slice must be one reflect.Value of a string followed by zero or more reflect.Value's of int's.

//func()
f := reflect.ValueOf(NoArgumentOrReturns)
f.Call(nil)	//returns a slice of length 0
//func(string, int) (int, error)
f := reflect.ValueOf(TwoParamsTwoReturns)
v := f.Call([]reflect.Value{reflect.ValueOf("hi"), reflect.ValueOf(0)})
//len(v) == 2, v[0] is a reflected int, v[1] is a reflected error
//func(string, ...int) bool
v := f.Call([]reflect.Value{
	reflect.ValueOf("θ"), //this is the only required element
	reflect.ValueOf(1),
	reflect.ValueOf(2),
	reflect.ValueOf(3),
})
//len(v) == 1 and v[0] is a reflected bool

In the last example (and ONLY in the last example,) f.Call could be replaced by f.CallSlice.

Invoke a method#

Go code:

Object.Method()

Equivalent reflect code:

Given an object with a method of a known name, use Value.MethodByName

obj := reflect.ValueOf(Object)
obj.MethodByName("Method").Call(nil)

If Method is the 2nd method on obj, this is equivalent:

obj.Method(1).Call(nil)

Value.Method will panic if there is no nth method, so use Value.NumMethod to make sure that

n < obj.NumMethod()

Invoking a method is essentially the same as calling a function. See that section for more information on Value.Call.

The method's receiver will always be the reflect.Value that you called Method or MethodByName on.

Iteration#

Go code:

for i := range iterable {
	//body
}
for k, v := range iterable {
	//body
}

Equivalent reflect code:

For arrays and slices simple iteration is straightforward.

for i := 0; i < iterable.Len(); i++ {
	//body
}
for i := 0; i < iterable.Len(); i++ {
	v := iterable.Index(i)
	//body
}

For maps, you must first call Value.MapKeys which returns a slice of reflect.Values and use Value.MapIndex on the items of the slice to get the value of the map at that key.

for _, key := range iterable.MapKeys() {
	//body
}
for _, key := range iterable.MapKeys() {
	v := iterable.MapIndex(key)
	//body
}

Channels are more verbose. Value.Recv() returns a reflect.Value and a boolean where the boolean is false if the reflected channel has been closed.

for {
	v, ok := iterable.Recv()
	if !ok {
		break
	}
	//body
}

Length#

To get the length of an object that you can use with len, call Value.Len

Go code:

ln := len(v)

Equivalent reflect code:

ln := v.Len()

Make#

For some types T and K:

Go code:

//SLICE
slice0 := []T{}
//	or
slice0 := make([]T)
slice1 := make([]T, length)
slice2 := make([]T, length, capacity)
//MAP
map0 := map[K]T{}
//	or
map0 := make(map[K]T)
map1 := make(map[K]T, initial_capacity)
//CHAN
chan0 := make(chan T)
chan1 := make(chan T, buffer_size)

Equivalent reflect code:

Where the type S below is a reflect.Type of []T, map[K]T, or chan T, respectively.

//SLICE
slice0 := reflect.MakeSlice(S, 0, 0)
slice1 := reflect.MakeSlice(S, length, length)
slice2 := reflect.MakeSlice(S, length, capacity)
//MAP
map0 := reflect.MakeMap(S)

There does not seem to be a way to make a map with an initial capacity via reflect. Fortunately there is no specific need to do this.

//CHAN
chan0 := reflect.MakeChan(S, 0)
chan1 := reflect.MakeChan(S, buffer_size)

Method expression#

Go code:

Given a type T with a method M,

m := T.M

Equivalent reflect code:

Unlike most entries in this codex, we are using reflect.Type instead of reflect.Value. Given a reflect.Value you can use the Value.Type method to get its reflect.Type value.

(Godoc tip: reflect.Type is an interface and the reflect package does not export any values that satisfy it so click on reflect.Type itself to see what you can do with it).

Like reflect.Value, reflect.Type has methods Type.NumMethod, Type.Method and Type.MethodByName that behave analogously to the methods on reflect (cf. Invoke a method) except they return values of reflect.Method and Type.MethodByName also returns a bool indicating success, rather than panicing.

Type.Method is a struct but the actual value we're interested in in this case is Method.Func

Given a reflect.Type T, we get the method M by

if M, ok := T.MethodByName("M"); ok {
	m = M.Func
}

If M is the 2nd method on T, this is equivalent:

M := T.Method(1).Func

Type.Method will panic if there is no nth method, so use Type.NumMethod to make sure that

n < obj.NumMethod()

New#

Go code:

p := &T{}
//	or
p := new(T)

Equivalent reflect code:

p := reflect.New(T)

Reslice#

Go code:

s = s[:5] //where len(s) < 5 but cap(s) >= 5

Equivalent reflect code:

s.SetLen(5)

Value.SetLen will panic if given a negative number or a number greater than that returned by Value.Cap for the given slice or when called on a reflect.Value of a nonslice.

Select#

Go code:

select {
case m1 := <-c1:
	...
case c2 <- m2:
	...
case m3, ok <- c3:
	...
default:
	...
}

Equivalent reflect code:

Given reflect.Value's matching c1, c2, c3, m2, as above, and named the same:

cases := []reflect.SelectCase{
	{Dir: reflect.SelectRecv,   Chan: c1},
	{Dir: reflect.SelectSend,   Chan: c2, Send: m2},
	{Dir: reflect.SelectRecv,   Chan: c3},
	{Dir: reflect.SelectDefault},
}
switch selected, recv, recvOK := reflect.Select(cases); selected {
case 0:
	//c1 was selected, recv is the value received
	//we get recvOK whether we need it or not
case 1:
	//c2 was selected, therefore m2 was sent
	//recv and recvOK are meaningless in this case
case 2:
	//c3 was selected, recv is the value received if recvOK == true
	//recvOK is false if c3 is closed
case 3:
	//the default case
	//recv and recvOK are meaningless in this case
}

Selecting with reflect is a bit cumbersome, but in many ways more flexible than the built in Go select statement as you can create very large dynamic slices of reflected channels at runtime.

Slice#

Go code:

sub0 := slice[2:5]
sub1 := slice[:5]
sub2 := slice[2:]

Equivalent reflect code:

Value.Slice handles slicing for reflect.Value's whose type is an array or slice.

sub0 := slice.Slice(2, 5)
sub1 := slice.Slice(0, 5)
sub2 := slice.Slice(2, slice.Len())

Synchronous Communication#

Value.Send and Value.Recv mirror the dual uses of the <- operator.

Go code:

c <- v
v := <-c
c, ok := <-c

Equivalent reflect code:

c.Send(x)
v, _ := c.Recv()
c, ok := c.Recv()

Type Conversion#

Go code:

vp := T(v)

Equivalent reflect code:

Given a reflect.Value, v, of some type, S, and a reflect.Type, T, where values of type S can be converted to T in ordinary Go.

vp := v.Convert(T)

If you want to make sure that S is convertible to T use Type.ConvertibleTo

if S := v.Type(); S.ConvertibleTo(T) {
	vp := v.Covert(T)
}

Type assert#

Go code:

if v, ok := SomeInterface.(ConcreteType); ok {
	...
}

Equivalent reflect code:

If you have a reflect.Type, T, of a noninterface type to check against, you can use Value.Elem like so

if SomeReflected.Elem().Type() == T {
	...
}

Value.Elem will panic if SomeReflected is not an interface (or a pointer) and will return the zero value of Elem().Type() if SomeReflected is nil.

Another tact is calling Value.Interface on a reflect.Value returns the unreflected value as an interface{}.

if v, ok := SomeReflected.Interface().(ConcreteType); ok {
	...
}

Value.Interface can panic if the reflect.Value is invalid or the value is an unexported read only field.

Value.CanInterface allows you to check if the call is safe

if SomeReflected.CanInterface() {
	if v, ok := SomeReflected.Interface().(ConcreteType) {
		...
	}
}

Type switch#

Go code:

switch v.(type) {
	...
}

Equivalent reflect code:

Given a reflect.Value v:

switch v.Type().Kind() {
	...
}

Type.Kind returns one of a set of constants defined under reflect.Kind. For the primitive types, the type switch is normal. Special handling is needed for each of reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, and reflect.Struct.

Zero value#

Go code:

When not using reflect we generally know the type and hence the zero value. Of course the simplest means is to declare a variable.

var v T

Equivalent reflect code:

When you're using reflect and need a type's zero value you need to pass a value of reflect.Type, say T, to reflect.Zero

reflect.Zero(T)