Don’t Use
reflect
Go 1.7 Release Party
Aug 8, 2016
Daisuke Maki @lestrrat
Don’t Use
reflect
Go 1.7 Release Party
Aug 8, 2016
Daisuke Maki @lestrrat
Don’t Use
reflect
Go 1.7 Release Party
Aug 8, 2016
Daisuke Maki @lestrrat
New Go Book!
無念!
Reflect
Dynamically
Change Behavior
All the cool kids are doing it
… in Go?
Performance
From The Book
Line Noise
@P=split//,".URRUUc8R";@d=split//,"nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/S/;print
Line Noise
in Go?
reflect.TypeOf((*Maybe)(nil)).Elem()
reflect.TypeOf((*Maybe)(nil)).Elem()
WTF
reflect.TypeOf((*Maybe)(nil)).Elem()
reflect.TypeOf((*Maybe)(nil)).Elem()
pointer to nil “Maybe”
reflect.TypeOf((*Maybe)(nil)).Elem()
reflect.TypeOf((*Maybe)(nil)).Elem()
Dereference the pointer reflect.Type
It’s an
Interface Type!
stringer = reflect.

TypeOf((*Stringer)(nil)).Elem()
if rv.Implements(stringer) {
…

}
Check If A Value Implements An Interface
• reflect.Type/Value usually requires a value to create
• But if you don’t want to create a variable just to create
an interface reflect.Type…
• Create a nil pointer, then dereference it!
reflect.TypeOf((*Maybe)(nil)).Elem()
Why Use reflect?
意訳「そこにreflectがあるから」
Sometimes, you
just have to
Otherwise, DON’T
New in Go1.7
禁句
「この機能、誰が嬉しいんだ?」
rv := reflect.ValueOf(…)
fv := rv.Field(1<<63-1) // 1.7 PANICs
if fv == reflect.Value{} {
// <1.6 silently returns zero value
}
Bug Fix
rv := reflect.ValueOf(…)
fv := rv.Field(1<<63-1) // 1.7 PANICs
if fv == reflect.Value{} {
// <1.6 silently returns zero value
}
Bug Fix
rv := reflect.ValueOf(…)
fv := rv.Field(1<<63-1) // 1.7 PANICs
if fv == reflect.Value{} {
// <1.6 silently returns zero value
}
Bug Fix
type Foo struct {
foo int // not exported
}
Bug? Fix
_, ok := reflect.
TypeOf(Foo{}).
MethodByName(“foo”)
fmt.Printf(“ok = %tn”)
Bug? Fix
_, ok := reflect.
TypeOf(Foo{}).
MethodByName(“foo”)
fmt.Printf(“ok = %tn”)
Bug? Fix
// go1.6 -> true
_, ok := reflect.
TypeOf(Foo{}).
MethodByName(“foo”)
fmt.Printf(“ok = %tn”)
Bug? Fix
// go1.7 -> false
// struct { Foo int; Bar string }
typ := reflect.StructOf([]reflect.StructField{
reflect.StructField{ Name: “Foo”, Type: reflect.Int},
reflect.StructField{ Name: “Bar”, Type: reflect.String},
})
Dynamically Declare
Anonymous Structs
rv := reflect.New(typ)
// v.Foo = 100
fv := rv.Elem().
FieldByName(“Foo”).
Set(reflect.ValueOf(100))
// &struct { Foo int; Bar string }{Foo:100, Bar:""}
fmt.Printf(“%#vn”, rv.Interface())
Dynamically Declare
Anonymous Structs
field := fv.FieldByName(“Foo”)
field.Tag.Get(“json”) // string
field.Tag.Lookup(“json”) // string, bool
Can Tell Difference Between
empty tag and non-existing tag
Happy hacking
with Go1.7
…and Don’t Use
reflect! :D

Don't Use Reflect - Go 1.7 release party 2016