updated on 2020-10-31
基本構文
func (レシーバ) メソッド名(引数) { // 処理 }
レシーバ
package main type T int func (t *T) f() { println("hi") } func main() { var v T // 以下の2行は同じ意味 (&v).f() v.f() }
(コンソール出力)
hi
hi
例: ユーザー定義型のレシーバー
package main import "fmt" type Hex int func (h Hex) String() string { // %x 基数16で表現する 10以上の数には小文字(a-f)を使用 return fmt.Sprintf("%x", int(h)) // fmt.Sprintfはfmt.Printfと違い、標準出力ではなくフォーマットした結果を文字列で返す } func main() { // 100をHex型として代入 var hex Hex = 100 // Stringメソッドを呼び出す fmt.Println(hex.String()) // 100=>16*6+1*4なので、16進数で64 hex = 160 fmt.Println(hex.String()) // 160=>16*10+1*0なので、16進数でa0 hex = 200 fmt.Println(hex.String()) // 200=>16*13+1*8なので、16進数でc8 }
(コンソール出力)
64
a0
c8
例: ポインタ型のレシーバ
package main import "fmt" type User struct { Name string } // メソッド(ポインタレシーバ) func (u *User)setName() { u.Name = "gopher" } func main() { u := new(User) u.setName() fmt.Println(u.Name) //=> gopherが出力される。 }
(コンソール出力)
gopher
例: 配列型のレシーバ
package main import "fmt" type Vector2D [2]float32 func (v Vector2D) Add(n Vector2D) Vector2D { return Vector2D{n[0] + v[0], n[1] + v[1]} } func main() { v1 := Vector2D{1.5, -1.0} v2 := Vector2D{2.2, 4.4} fmt.Println(v1.Add(v2)) }
(コンソール出力)
[3.7 3.4]
例: ポインタ型のレシーバ
package main type MyInt int func (n *MyInt) Inc() { *n++ } func main() { var n MyInt println(n) // 0 // ポインタを用いたメソッドの呼び出しでは、&は省略しても良い // (&n).Inc() n.Inc() println(n) // 1 }
(コンソール出力)
0
1
メソッドも値として扱える
メソッドを値として扱う例
package main import "fmt" type Hex int func (h Hex) String() string { return fmt.Sprintf("%x", int(h)) } func main() { // 100をHex型として代入 var hex Hex = 100 // メソッド値として代入 f := hex.String fmt.Println(f()) }
(コンソール出力)
64
メソッドを表す式
レシーバを第1引数とした関数になる
package main import "fmt" type Hex int func (h Hex) String() string { return fmt.Sprintf("%x", int(h)) } func main() { // 100をHex型として代入 var hex Hex = 100 // メソッド値 // f := hex.String // fmt.Println(f()) // メソッド式 f := Hex.String fmt.Printf("%T\n%s\n", f, f(hex)) }
(コンソール出力)
func(main.Hex) string
64