この記事ではGoの名前付き戻り値の使い方と、そのメリット・デメリットについてまとめます。
最後まで読めば、使い方とその利点・欠点が初学者でも理解できるはずです。
記事におけるGoのバージョンはgo1.23.4 darwin/amd64です。
【Golang】名前付き戻り値の使い方
名前付き戻り値とは文字どおり、戻り値に名前をつける機能です。
具体例で説明します。
具体例: 名前付き戻り値を使わない場合
まずは名前付き戻り値を使わずに書いた場合のサンプルコードです。
package main
import "fmt"
func main() {
s, d := sumDiff(10, 3)
fmt.Printf("sum = %d, diff = %d\n", s, d)
// 出力: sum = 13, diff = 7
}
func sumDiff(a, b int) (int, int) {
sum := a + b
diff := a - b
return sum, diff
}
このsumDiff
関数を名前付き戻り値を使って書くと次のようになります。
具体例: 名前付き戻り値を使った場合
package main
import "fmt"
func main() {
s, d := sumDiff(10, 3)
fmt.Printf("sum = %d, diff = %d\n", s, d)
// 出力: sum = 13, diff = 7
}
// 戻り値に sum, diff と名前を付ける
func sumDiff(a, b int) (sum int, diff int) {
// 変数 sum, diff があらかじめ用意されている
sum = a + b
diff = a - b
// return だけ書けば sum と diff の値がそのまま返る
return
}
戻り値にデータ型だけでなくsum
, diff
と名前をつけています。
このsum
, diff
はゼロ値で初期化されているため、変数としてそのまま使えます。
よって、関数内でのsum
, diff
の定義は不要です(:=
→ =
)。
また、関数の最後では単にreturn
だけ記述すればOKです。
【Golang】名前付き戻り値のメリット・デメリット
ここからは名前付き戻り値のメリット・デメリットについてです。
メリット
- 「この関数は何を返すのか?」が宣言部分を見るだけですぐわかる
- 変数の定義が不要になるため、コードが短くなる
- 空のreturn文を書けば良いため、シンプルに記述できる
名前付き戻り値を活用することで全体的な記述量を抑えてスッキリ書くことが可能です。
デメリット
- 関数が長い場合、returnだけだと何を返すのか分かりにくい
- 変数のスコープが広くなってしまう
- 戻り値の型から変数名を推論できる場合はむしろ冗長
関数が長い場合、空のreturn文だけだと「この関数は何を返すんだっけ?」と宣言部分に戻って見にいく必要があります。
また、名前付き戻り値はその関数全体をまたがるスコープの広い変数となってしまうため、逆に可読性を損なってしまう時も多いです。
さらに、以下のように戻り値の型から変数名を推論できる場合、わざわざ名前を付けるのは冗長に思えます。
// 戻り値に user と名前を付けずとも、*User 型の変数名を user とすることは十分予測できる
func GetUserInfo(userID int) (user *User, err error) { ... }
そこそこ複雑な関数で名前付き戻り値を使ってしまうと、たとえ記述量は抑えられるとしても、トータルでの可読性を損なってしまうことが多いです。
名前付き戻り値の使い所
上記のデメリットがあるため、名前付き戻り値はあまり積極的には使われません。
次のようなケースでのみ、「もしかしたら名前付き戻り値を使ってスッキリ書けるかも?」くらいの温度感で使用を検討すると良いでしょう。
- とてもシンプルな関数
- 複数の同じ型の値を返す関数
- 型から戻り値の変数が予測つかない関数
まとめ
この記事では名前付き戻り値の使い方とメリット・デメリットについてまとめました。
細かい文法も1つ1つアウトプットしていきます。
コメント