Go 言語はコンパイル言語であるため、関数を記述する順序は関係ありませんが、読みやすさを考慮すると、main() 関数をファイルの前に記述し、他の関数をファイルの中に記述するのが最善です。特定の論理順序 (たとえば、関数は一連の呼び出しによって記述されます)。
複数の関数を記述する主な目的は、多くのコード行を必要とする複雑な問題を、解決するために一連の単純なタスクに分解することです。さらに、同じタスク (関数) を複数回呼び出すことができるため、コードの再利用が容易になります (実際、優れたプログラムは、DRY 原則に細心の注意を払っています。つまり、自分自身を繰り返さない (Don’trepeat Yourself)。これは、特定のタスクを実行するコードがプログラム内に 1 回しか出現できないことを意味します。
関数がコード ブロックの最後の行}
または return ステートメントの前まで実行されると、関数は終了します。return ステートメントには 0 個以上のパラメーターを含めることができ、これらのパラメーターは呼び出し元の戻り値として使用されます。単純な return ステートメントfor の無限ループを終了したり、ゴルーチンを終了したりすることもできます。
Go 言語には 3 種類の関数があります。
- 通常の名前付き関数
- 匿名関数またはラムダ関数
- 方法
通常の関数宣言(定義)
関数宣言には、関数名、仮パラメータのリスト、戻り値のリスト (オプション)、および関数本体が含まれます。
func 関数名(パラメータリスト)(返回值列表){
コード
}
仮パラメータリストは、関数のパラメータ名とパラメータの型を記述します。これらのパラメータは、パラメータ呼び出し元によって値が提供されるローカル変数です。戻り値リストは、関数の戻り値の変数名と型を記述します。関数の場合、名前のない変数を返すか、値を返さない場合、戻り値リストのかっこは省略できます。
関数宣言に戻り値リストが含まれていない場合、以下の Hypot 関数では、関数本体が実行された後、値は返されません。
func hypot(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(3,4)) // "5"
x と y は仮パラメータ名、3 と 4 は呼び出し時に渡される実数です。関数は float64 型の値を返します。戻り値にも仮パラメータと同じ名前を付けることができます。この場合、各戻り値ははローカル変数として宣言され、戻り値の型に応じて 0 に初期化されます。
関数が宣言されたときに戻り値のリストが含まれている場合、関数が明らかに最後まで実行できない場合を除き、関数は return ステートメントで終了する必要があります。たとえば、関数の最後でパニック例外が呼び出されるか、関数内に無限ループがあります。
Hypot 関数と同様に、仮パラメータまたは戻り値のグループが同じ型を持つ場合、仮パラメータごとにパラメータの型を記述する必要はありません。次の 2 つの宣言は同等です。
func f(i, j, k int, s, t string) { /* ... */ }
func f(i int, j int, k int, s string, t string) { /* ... */ }
以下に、2 つの int パラメーターと 1 つの int 戻り値を持つ関数を宣言する 4 つのメソッドを示します。空白の識別子_
は、特定のパラメーターが使用されていないことを強調できます。
func add(x int, y int) int {return x + y}
func sub(x, y int) (z int) { z = x - y; return}
func first(x int, _ int) int { return x }
func zero(int, int) int { return 0 }
fmt.Printf("%T\n", add) // "func(int, int) int"
fmt.Printf("%T\n", sub) // "func(int, int) int"
fmt.Printf("%T\n", first) // "func(int, int) int"
fmt.Printf("%T\n", zero) // "func(int, int) int"
関数の型は関数の識別子と呼ばれ、2 つの関数の仮引数リストと戻り値リストの変数の型が 1 対 1 に対応する場合、2 つの関数は同じ型と識別子を持つとみなされます。 、仮パラメータおよび戻り値変数名は、関数識別子や省略された引数の型の形式で表現できるかどうかには影響しません。
関数が呼び出されるたびに、宣言の順序ですべてのパラメータに対して実際のパラメータ (パラメータ値) を提供する必要があります。関数が呼び出されるとき、Go 言語にはデフォルトのパラメータ値はなく、パラメータによって仮パラメータを指定する方法はありません。名前、つまり仮パラメータと戻り値の変数名は、関数の呼び出し元にとっては意味がありません。
関数では、実パラメータは値によって渡されるため、関数の仮パラメータは実パラメータのコピーであり、仮パラメータの変更は実パラメータには影響しません。ただし、実パラメータに参照が含まれている場合は、ポインタ、スライス(スライス)、マップ、関数、チャネルなどの型の場合、実際のパラメータは関数の間接参照により変更される可能性があります。
関数の戻り値
Go 言語は複数の戻り値をサポートしており、関数実行後に複数の戻り値パラメータを簡単に取得できます。Go 言語では、関数実行中に発生する可能性のあるエラーを返すために、複数の戻り値の最後の戻り値パラメータをよく使用します。サンプルコードは次のとおりです。
conn、err:= connectToNetwork()
このコードでは、connectToNetwork は 2 つのパラメーターを返します。conn は接続オブジェクトを表し、err はエラー メッセージを返します。
他のプログラミング言語の関数の戻り値
- C/ C++言語は戻り値を 1 つだけサポートします。複数の値を返す必要がある場合は、構造体を使用して結果を返すか、パラメーターにポインター変数を使用して、から渡された変数値を変更する必要があります。そのため、C++ 言語では、安全性を考慮して、パラメーターがデータを返すときにポインターの代わりに「参照」を使用することが推奨されています。
- C#言語には複数の戻り値の機能がありませんが、C# 言語で後から追加された ref および out キーワードは、関数の呼び出しパラメーターを通じて関数本体内の変更されたデータを取得できます。
- lua 言語にはポインターがありませんが、複数の戻り値がサポートされているため、大きなデータ ブロックを使用する場合に非常に便利です。
Go 言語は安全なポインターと複数の戻り値の両方をサポートしているため、ロジックの記述には関数を使用する方が便利です。
1) 同じ型の戻り値
戻り値の型が同じ場合は、複数の戻り値の型を括弧で囲み、各戻り値の型をカンマで区切ります。
return ステートメントを使用して返す場合、値リストの順序は、関数によって宣言された戻り値の型と一致する必要があります。サンプル コードは次のとおりです。
func typedTwoValues() (int, int) {
return 1, 2
}
func main() {
a, b := typedTwoValues()
fmt.Println(a, b)
}
コード出力結果:
1 2
純粋な型の戻り値はコードの可読性にとってあまり優しくありません。特に同じ型の戻り値が出現した場合、各戻りパラメーターの意味を区別することができません。
2) 変数名を含む戻り値
Go 言語は戻り値の名前付けをサポートしているため、戻り値はパラメーターと同じパラメーター変数名と型になります。
名前付き戻り値変数のデフォルトは、型のデフォルト値です。つまり、数値の場合は 0、文字列の場合は空の文字列、ブール値の場合は false、ポインタの場合は nil などです。
次のコードの関数には 2 つの整数の戻り値があります。関数が宣言されると、戻り値には a と b という名前が付けられるため、関数の戻り値は関数本体で直接割り当てることができます。名前付き戻り値の関数本体では、メソッドを使用するには、関数の終了前に return ステートメントを明示的に使用して返す必要があります。コードは次のとおりです。
func namedRetValues() (a, b int) {
a = 1
b = 2
return
}
コードの説明は次のとおりです。
- 1 行目では、2 つの整数の戻り値に a と b という名前を付けます。
- 3行目と4行目のreturn valueという変数はこの関数のレイアウト変数と同じ効果を持ち、戻り値を代入して取得することができます。
- 6行目では、関数が名前付き戻り値を使用する場合、戻り値のリストに値を入力することはできませんが、値を入力することも可能です。次のコードの実行効果は、上記のコードの実行結果と同じです。上記のコード。
func namedRetValues() (a, b int) { a = 1 return a, 2 } ※関数 namedRetValues() は、aとb という2つの整数型の戻り値を持ちます。 ※ a には1を代入します。 ※ aと2を返します。
ヒント
同じ型の戻り値と名前付き戻り値のいずれか 1 つしか選択できません。以下のコードのようにこれらが混在するとコンパイル エラーが発生します。
func namedRetValues() (a, b int, int)
コンパイルエラーメッセージ:
mixed named and unnamed function parameters
意味: 関数パラメータに名前付きパラメータと名前なしパラメータが混在しています。

関数が定義された後、現在のコードは、呼び出すことによって、呼び出された関数にジャンプして実行できます。呼び出し前の関数のローカル変数は保存され、失われません。呼び出された関数の実行が終了すると、次の値に復元されます。呼び出し関数。関数の次の行ではコードの実行が継続され、以前のローカル変数にも引き続きアクセスできます。
関数内のローカル変数は関数本体内でのみ使用でき、関数呼び出し終了後は解放され無効になります。
Go言語の関数呼び出し形式は以下の通りです。
返回值变量列表 = 函数名(参数列表)
以下に各セクションの説明を示します。
- 関数名: 呼び出される関数の名前。
- パラメータ リスト: パラメータ変数はカンマで区切られ、末尾がセミコロンで終わる必要はありません。
- 戻り値変数リスト:複数の戻り値はカンマで区切られます。
たとえば、加算関数の呼び出しスタイルは次のようになります。
result := add(1,1)