Go言語 – 6.関数・メソッド

2019-01-30Go言語

関数・メソッド

関数の定義

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)
そうしないと、値を設定できません。

 

株式会社システムトラスト

人材募集中です。

システムトラストでは、システムエンジニア、プログラマーなどを随時募集中です。気軽にご相談ください。

お問合せ