Go言語のfieldがメソッドによって更新されないっぽい?
問題
Golangのstructに生えてるメソッドによって、structのfieldを更新しようとしたけど、変わってないっぽい?
package main import "fmt" type Ship struct { name string } func (s Ship) ChangeName() string { s.name = s.name + "改" return s.name } func main() { yudachi := Ship{"夕立"} fmt.Printf("%+v\n", yudachi) // 夕立 var name string name = yudachi.ChangeName() fmt.Println(name) // 返り値は夕立改 fmt.Printf("%+v\n", yudachi) // しかし夕立自身は変わってない }
なんでっぽい?
原因
structに生えるメソッドの定義には二種類あるっぽい(で、callerにおいてstruct自身がポインタかどうかは問わないっぽい)
// 値が来る func (s MyStruct) Foo() { fmt.Printf("%T", s) // MyStruct } // ポインタで来る func (s *MyStruct) Bar() { fmt.Printf("%T", s) // *MyStruct }
解決
package main import "fmt" type Ship struct { name string } func (s Ship) ChangeName() string { s.name = s.name + "改" // fmt.Printf("%T\n", s) return s.name } func (s *Ship) ChangeNameMore() string { s.name = s.name + "改二" // fmt.Printf("%T\n", s) return s.name } func main() { yudachi := Ship{"夕立"} // yudachi := &Ship{"夕立"} これでもいい fmt.Printf("%T\n", yudachi) fmt.Printf("%+v\n", yudachi) // 夕立 var name string name = yudachi.ChangeName() fmt.Println(name) // 返り値は夕立改 fmt.Printf("%+v\n", yudachi) // しかし夕立自身は変わってない name = yudachi.ChangeNameMore() fmt.Println(name) // 返り値は夕立改二 fmt.Printf("%+v\n", yudachi) // ポインタ渡しなので夕立自身も変わる }
golangおもしろいっぽい!
夕立改二描きました pic.twitter.com/10qxREyggP
— 囲碁みく (@gsx_R_yoshimura) 2014, 2月 23
DRY