Upload
lestrrat
View
1.343
Download
0
Embed Size (px)
Citation preview
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//,".URRUU\c8R";@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 = %t\n”)
Bug? Fix
_, ok := reflect. TypeOf(Foo{}). MethodByName(“foo”)
fmt.Printf(“ok = %t\n”)
Bug? Fix
// go1.6 -> true
_, ok := reflect. TypeOf(Foo{}). MethodByName(“foo”)
fmt.Printf(“ok = %t\n”)
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(“%#v\n”, 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