関数

Go言語の関数引数の基本と使い方について解説

この記事では、Go言語で関数を定義する際の引数の使い方について解説します。

引数を利用することで、関数に外部から値を渡し処理を柔軟に実行できる仕組みを確認します。

実際のコード例に沿って、基本的な設定方法や活用方法をわかりやすく説明します。

関数の基本構造

関数の定義と呼び出し

Goでは、関数はキーワードfuncを使って定義し、任意の引数を受け取ることができます。

関数定義では、返り値の型も明示する必要があります。

関数はmain関数などから呼び出して利用します。

以下は、引数として渡された文字列を表示するシンプルな例です。

package main
import "fmt"
// sampleFunction は文字列を受け取り表示する関数です。
func sampleFunction(message string) {
	// 受け取ったメッセージを表示する
	fmt.Println(message)
}
func main() {
	// sampleFunction を呼び出して "Hello, Go!" を表示する
	sampleFunction("Hello, Go!")
}
Hello, Go!

戻り値の設定

Goの関数は、返り値の型を関数ヘッダで宣言し、関数内でreturn文を使って返します。

返り値は一つまたは複数が定義できます。

以下は、2つの整数の和を返す例です。

package main
import "fmt"
// add は2つの整数を受け取り、その合計を返す関数です。
func add(a int, b int) int {
	return a + b
}
func main() {
	// add 関数を呼び出し、結果を表示する
	result := add(3, 5)
	fmt.Println("結果は", result)
}
結果は 8

引数の基本

単一引数の定義と利用

関数は単一の引数を受け取ることができます。

引数の型は必ず指定する必要があり、受け取った値を関数内でそのまま利用したり加工したりできます。

以下は、名前を受け取って挨拶する例です。

package main
import "fmt"
// greet は1つの文字列引数を受け取り、挨拶メッセージを表示する関数です。
func greet(name string) {
	fmt.Println("こんにちは", name)
}
func main() {
	// greet 関数を呼び出して "太郎" に挨拶する
	greet("太郎")
}
こんにちは 太郎

複数引数の定義方法

関数では複数の引数をカンマ区切りで定義することができます。

各引数は個別に型を指定するか、同じ型の場合はまとめて記述できます。

以下は、2つの整数を受け取り乗算した結果を返す例です。

package main
import "fmt"
// multiply は2つの整数引数を受け取り、その乗算結果を返す関数です。
func multiply(x int, y int) int {
	return x * y
}
func main() {
	// multiply 関数を呼び出して2つの数を乗算する
	result := multiply(4, 3)
	fmt.Println("乗算結果は", result)
}
乗算結果は 12

引数の種類と渡し方

値渡しとポインタ渡しの違い

Goでは、関数に引数を渡す際、基本的に値渡しとなります。

つまり、関数内で引数の値を変更しても、呼び出し元の変数には影響しません。

一方、ポインタ渡しを利用すると、変数のアドレスを渡すため、関数内での変更が呼び出し元にも反映されます。

値渡しの特徴

以下のサンプルは、値渡しの特徴として、関数内で値を変更しても元の変数は変わらないことを示す例です。

package main
import "fmt"
// incrementValue は、受け取った値をインクリメントするが、呼び出し元の値には影響しません。
func incrementValue(val int) {
	val++
	fmt.Println("関数内の値:", val)
}
func main() {
	number := 10
	incrementValue(number)
	fmt.Println("main内の値:", number)
}
関数内の値: 11
main内の値: 10

ポインタ渡しの特徴

次の例では、ポインタを使って引数を渡すことで、関数内での変更が呼び出し元の変数にも反映されることを示します。

package main
import "fmt"
// incrementPointer は、受け取ったポインタの示す値をインクリメントします。
func incrementPointer(val *int) {
	*val++
	fmt.Println("関数内の値:", *val)
}
func main() {
	number := 10
	incrementPointer(&number)
	fmt.Println("main内の値:", number)
}
関数内の値: 11
main内の値: 11

変数長引数の使い方

Goでは、引数の数が可変となる変数長引数(variadic function)を定義できます。

変数長引数は、スライスとして関数内で扱うため、渡された引数の数に応じて処理を行うことが可能です。

定義方法

変数長引数は、型の前に...を付けて定義します。

以下は、受け取った整数の合計を計算する例です。

package main
import "fmt"
// sum は可変長引数として受け取った整数の合計を返します。
func sum(numbers ...int) int {
	result := 0
	for _, num := range numbers {
		result += num
	}
	return result
}
func main() {
	// sum 関数を呼び出して複数の整数の合計を求める
	total := sum(1, 2, 3, 4)
	fmt.Println("合計は", total)
}
合計は 10

注意点

変数長引数は、関数の最後のパラメータとして定義しなければなりません。

また、引数が渡されなかった場合、内部では空のスライスとして扱われ、ループ処理などが安全に行える点に注意してください。

具体例で確認する関数引数の活用

単一引数を利用する関数例

以下のコードは、単一の引数として文字列を受け取り、その内容を表示する関数の利用例です。

シンプルな処理ですが、引数の受け渡しがどのように行われるかを確認できます。

package main
import "fmt"
// displayMessage は受け取ったメッセージを表示します。
func displayMessage(message string) {
	fmt.Println("メッセージ:", message)
}
func main() {
	// displayMessage を呼び出してメッセージを表示する
	displayMessage("Goはシンプルで楽しい言語です!")
}
メッセージ: Goはシンプルで楽しい言語です!

複数引数を組み合わせた関数例

この例では、2つの文字列を受け取り、それらを結合して結果を返す関数を利用します。

複数の引数を使うことで、より複雑な処理が可能となります。

package main
import "fmt"
// combineStrings は、2つの文字列を結合し、1つの文字列として返します。
func combineStrings(str1 string, str2 string) string {
	return str1 + " " + str2
}
func main() {
	// combineStrings 関数を呼び出して文字列を結合する
	result := combineStrings("こんにちは", "世界")
	fmt.Println(result)
}
こんにちは 世界

配列やスライスを引数に渡す場合

配列やスライスなどのコレクションも関数の引数として渡すことができます。

以下は、スライスの全要素を順に表示する例です。

package main
import "fmt"
// printElements は受け取ったスライスの各要素を表示します。
func printElements(elements []int) {
	for i, value := range elements {
		fmt.Printf("要素 %d: %d\n", i, value)
	}
}
func main() {
	// 数値が格納されたスライスを作成し、printElements で表示する
	numbers := []int{10, 20, 30, 40}
	printElements(numbers)
}
要素 0: 10
要素 1: 20
要素 2: 30
要素 3: 40

コーディング時のポイント

型指定に関する考慮事項

Goでは型指定が必須となっており、引数や返り値の型を正しく宣言することが大切です。

たとえば、同じ型の複数の引数であれば下記のようにまとめて記述できます。

また、型指定が正確なコードは後々の保守性や可読性の向上に寄与します。

下記のコードは、複数の整数引数を受け取り、数式 (a+b×c) を用いて計算する例です。

package main
import "fmt"
// calculate は昇順で与えられた整数に対し、数式 \( a + b \times c \) の結果を返します。
func calculate(a, b, c int) int {
	return a + b*c
}
func main() {
	// calculate 関数を呼び出し数式の結果を確認する
	result := calculate(2, 3, 4)
	fmt.Println("計算結果は", result)
}
計算結果は 14

よくあるエラーと対処方法

関数の利用時によくあるエラーの一例として、引数の型の不一致が挙げられます。

たとえば、関数が文字列を受け取るべき場所に整数を渡すとコンパイルエラーが発生します。

下記のコメント付きサンプルは、エラー例を示しつつ正しい型指定の大切さを説明しています。

package main
import "fmt"
// wrongFunction のコメントとして、間違った型の引数を渡した場合のエラー例を記述します。
// 例:
// func sample(text string) { ... }
// sample(123) // コンパイルエラー: cannot use 123 (type int) as type string
func main() {
	fmt.Println("よくあるエラーと対処方法の例はコード内のコメントを参照")
}
よくあるエラーと対処方法の例はコード内のコメントを参照

コードの可読性向上の工夫

コードの可読性は保守性を高めるために重要です。

意味のある変数名や関数名を英語表記で統一し、必要なコメントを付けることで、コードを読みやすく保つ工夫が求められます。

以下は、データ処理を行う関数の例です。

package main
import "fmt"
// processData は整数スライス内の数値を合計して返す関数です。
func processData(data []int) int {
	total := 0
	// 各要素を合計する処理
	for _, value := range data {
		total += value
	}
	return total
}
func main() {
	// sampleData は処理対象のデータの例です。
	sampleData := []int{5, 10, 15}
	result := processData(sampleData)
	fmt.Println("合計:", result)
}
合計: 30

まとめ

この記事では、Go言語の関数定義と呼び出し、戻り値の設定、単一・複数引数の利用、値渡しやポインタ渡し、変数長引数などの基本的な使い方と特徴を具体例を交えて解説しました。

各サンプルコードを通して関数引数の取り扱い方法が理解できる内容であり、開発現場での実践的な知識が得られます。

ぜひ、実際のプロジェクトに活かしてみてください。

関連記事

Back to top button
目次へ