Go言語 – 6.関数・メソッド
関数・メソッド
関数の定義
func 関数名(引数名 型) 戻り値の型 {
処理
}
例:引数と戻り値を共に、カンマ区切りで複数指定した。
// 2つの文字列を入力すると、2つの文字列を返す関数 // 入力 // strOrg string // strAdd string // 復帰 // string // string func subFunc(strOrg string, strAdd string) (string, string) { var strAppend string strAppend = strOrg + strAdd // デフォルト文字列と、デフォルト+拡張文字列を返す return strOrg, strAppend }
関数の呼出し・戻り値の取得
上で作った関数を呼び出してみます。
// 上のsubFunc関数を呼出して、戻り値を取得する func main() { var str1 string var str2 string str1, str2 = subFunc("メイン関数", "サブ関数") fmt.Println(str1, str2) } 結果... メイン関数 メイン関数サブ関数
1つ目の戻り値は無視する例。
// 上のsubFunc関数を呼出して、戻り値を取得する func main() { var str2 string _, str2 = subFunc("メイン関数", "サブ関数") fmt.Println(str2) } 結果... メイン関数サブ関数
deferステートメント
deferステートメントで記述した関数は、関数から復帰する直前(一番最後)に実行されます。
関数内で、複数のdeferステートメントを記載した場合は、先に書いたdeferステートメントの関数以外で、一番最後に実行されます。
※ファイルのクローズ等、開放しなければならないリソースの処理に利用します。
// strAppendを計算した後、順にccc、bbb、aaaを表示してから復帰します // (deferを複数書いた場合は、最初に書いたものが一番最後に実行されます) func subFunc(strOrg string, strAdd string) (string, string) { var strAppend string defer println("aaa") defer println("bbb") defer println("ccc") strAppend = strOrg + strAdd return strOrg, strAppend }
ここまでのコードで、実行可能なコードは下記の通りです。
// 全体 package main import "fmt" // 入力パラメータ2つ、戻り値も2つ func subFunc(strOrg string, strAdd string) (string, string) { var strAppend string defer println("aaa") defer println("bbb") defer println("ccc") strAppend = strOrg + strAdd return strOrg, strAppend } // メイン関数 func main() { var str1 string var str2 string // 関数の呼出し・戻り値の取得(戻り値を2つとも取得) str1, str2 = subFunc("メイン関数", "サブ関数") fmt.Println(str1, str2) } 結果... ccc bbb aaa メイン関数 メイン関数サブ関数
メソッド
メソッドは構造体と結び付けることで作成できます。
下の例では、typeString構造体に、AddやOrgという名前で2つのメソッドを作成しています。
メソッドの定義
func (引数名 型) メソッド名(引数名 型) 戻り値の型 {
処理
}
package main import "fmt" // 構造体 type typeString struct {str1, str2 string} // メソッド(結合) func (ans typeString) Add() string { return ans.str1 + ans.str2 } // メソッド(str1を返す) func (ans typeString) Org() string { return ans.str1 } // メイン func main() { var ansStr typeString ansStr = typeString{"デフォルト", "拡張"} fmt.Println(ansStr.Org(), ansStr.Add()) } 結果... デフォルト デフォルト拡張
今度は、構造体に値をセットする際に、メソッドを使ってみます。
package main import "fmt" // 構造体 type typeString struct {str1, str2 string} // メソッド(結合) func (ans typeString) Add() string { return ans.str1 + ans.str2 } // メソッド(str1を返す) func (ans typeString) Org() string { return ans.str1 } // メソッド(値セット) func (ans *typeString) SetStr1(strParam string) { ans.str1 = strParam } func (ans *typeString) SetStr2(strParam string) { ans.str2 = strParam } func main() { var ansStr typeString ansStr.SetStr1("デフォルト") ansStr.SetStr2("拡張") fmt.Println(ansStr.Org(), ansStr.Add()) } 結果... デフォルト デフォルト拡張
値セットのメソッドで、レシーバーの型をポインターにしています(ans *typeString)
そうしないと、値を設定できません。