メソッドも関数のように扱えます。
メソッド値
メソッドを値のように扱う事をメソッド値と呼びます。
変数への代入
関数と同様、メソッドも変数へ代入する事が出来ます。
package main
import (
"fmt"
)
// 構造体定義
type myStruct struct {
num int
}
// メソット定義
func (m myStruct) add(val int) int {
return m.num + val
}
func main() {
m := myStruct{num: 10}
// メソッドを変数へ代入する。
funcVal := m.add
fmt.Println(funcVal(15)) // 25 が表示される。
}
関数定義変数への代入
シグネチャーが同じ関数定義の変数へメソッドを代入する事が出来ます。
package main
import (
"fmt"
)
// 構造体定義
type myStruct struct {
num int
}
// メソット定義
func (m myStruct) add(val int) int {
return m.num + val
}
// 関数定義
type myFunc func(int) int
func main() {
var myFunc myFunc
m := myStruct{num: 10}
// 関数型の変数へメソッドを代入する。
myFunc = m.add
// 実行
fmt.Println(myFunc(15)) // 25 が表示される。
}
メソッド式
メソッドから関数を作成する事が出来ます。関数の第一引数はレシーバになります。
package main
import (
"fmt"
)
// 構造体定義
type myStruct struct {
num int
}
// メソット定義
func (m myStruct) add(val int) int {
return m.num + val
}
func main() {
m := myStruct{num: 10}
// 型のメソッド定義
add := myStruct.add
// 実行
fmt.Println(add(m, 15)) // 25 が表示される。
}
以下のような書き方も出来ます。
package main
import (
"fmt"
)
// 構造体定義
type myStruct struct {
num int
}
// メソット定義
func (m myStruct) add(val int) int {
return m.num + val
}
func main() {
m := myStruct{num: 10}
// 実行
fmt.Println(myStruct.add(m, 15)) // 25 が表示される。
}
メソッドの実態
Goのメソッドは以下のような関数に置き換えられているようです。
// メソッド
func (m myStruct) add(val int) int {
return m.num + val
}
// 関数
func add(m myStruct, val int) int {
return m.num + val
}