Go には、オブジェクト指向のクラスや、そのメンバーであるメソッドは存在しません。そのかわりに、Go では、構造体とは別に定義された関数を、構造体と関連づけることによって、オブジェクト指向のメソッドの替わりにしています。このように構造体に関連づけられた関数のことを、Go でも、メソッド(method)と呼んでいます。
package main
import ("fmt"
"math/rand"
"time"
)
type janken struct {
name string
hand string
}
func (j *janken) play() {
hands := [] string {"グー", "チョキ", "パー"}
n := rand.Intn(3)
j.hand = hands[n]
}
func main() {
rand.Seed(time.Now().Unix())
you := new(janken)
opp := new(janken)
you.name = "あなた"
opp.name = "相手"
you.play()
opp.play()
fmt.Printf("%sは%sです\n",you.name, you.hand)
fmt.Printf("%sは%sです\n",opp.name, opp.hand)
switch {
case you.hand == opp.hand:
println("おあいこです")
case you.hand == "グー" && opp.hand == "チョキ":
println("あなたの勝ちです")
case you.hand == "チョキ" && opp.hand == "パー":
println("あなたの勝ちです")
case you.hand == "パー" && opp.hand == "グー":
println("あなたの勝ちです")
default:
println("相手の勝ちです")
}
}
あなたはグーです
相手はグーです
おあいこです
あなたはパーです
相手はグーです
あなたの勝ちです
あなたはパーです
相手はチョキです
相手の勝ちです
func (j *janken) play() {
メソッドは、構造体と同じく、パッケージのルートで定義します。
メソッドの定義は、func キーワードとメソッド名の間に、( と ) で囲んでレシーバーというものを指定します。
この例では、j という識別子に構造体 janken が、関連づけられます。
注意が必要なのは、janken の前に *(アスタリスク)がついていることです。* がついていると janken 構造体が参照渡しとして j という識別子に結びつけれます。* がついていないと値渡しになります。
j.hand = hands[n]
j.hand で構造体 janken の hand フィールドにアクセスできます。ここで、もし janken の前の * を記述していない場合は、あくまでも、コピーされた janken 構造体の hand フィールドが書き換えられるだけで、もとの janken 構造体の hand フィールドは書き換えられません。実際に * を外して実行すると、実行結果は次のようになります。
あなたはです
相手はです
おあいこです
you := new(janken)
今回のサンプルの場合は、構造体の変数を、参照型で宣言しても、値型で宣言しても、実行結果は同じです。
you.play()
メソッドにを呼び出すには、変数名 . メソッド名 ( ) と記述します。