missing return at end of function の原因と直し方
戻り値のある関数は、すべての実行経路の末尾でreturn文が必要です。if文の片方の分岐にしかreturnが無いと、関数全体の末尾に到達しうると判断されエラーになります。
エラーメッセージの読み方
./main.go:10:1: missing return
./main.go- ファイル名
10- 行番号
1- 列番号
missing return- 詳細メッセージ — 何が問題だったか
このエラーが出る典型パターン
パターン1
1 package main 2 3 import "fmt" 4 5 func abs(x int) int { 6 if x < 0 { 7 return -x 8 } 9 ^ 10 } 11 12 func main() { 13 fmt.Println(abs(-5)) 14 }
./main.go:10:1: missing return
ifブロックにしかreturnが無いため、x >= 0の場合に関数が値を返さずに終わってしまいます。elseに相当する戻り値が必要です。
直し方: (空) を return x にします。
広告
広告スロット(未設定)
パターン2
1 package main 2 3 import "fmt" 4 5 func classify(x int) string { 6 if x < 0 { 7 return "negative" 8 } 9 ^ 10 } 11 12 func main() { 13 fmt.Println(classify(-5)) 14 }
./main.go:10:1: missing return
x < 0の場合以外の戻り値が書かれていないため、コンパイラは関数の末尾に到達しうると判定します。
直し方: (空) を return "non-negative" にします。
パターン3
1 package main 2 3 import "fmt" 4 5 func bigger(a, b int) int { 6 if a > b { 7 return a 8 } 9 ^ 10 } 11 12 func main() { 13 fmt.Println(bigger(3, 7)) 14 }
./main.go:10:1: missing return
a > bでない場合(bの方が大きいか同じ場合)のreturnが無いため、関数の末尾に到達する経路が残ります。
直し方: (空) を return b にします。
パターン4
1 package main 2 3 import "fmt" 4 5 func sign(x int) int { 6 if x > 0 { 7 return 1 8 } 9 ^ 10 } 11 12 func main() { 13 fmt.Println(sign(-5)) 14 }
./main.go:10:1: missing return
x <= 0の場合の戻り値が書かれていないため、コンパイラは関数末尾への到達を許してしまいます。
直し方: (空) を return -1 にします。
パターン5
1 package main 2 3 import "fmt" 4 5 func describe(n int) string { 6 if n == 0 { 7 return "zero" 8 } 9 ^ 10 } 11 12 func main() { 13 fmt.Println(describe(5)) 14 }
./main.go:10:1: missing return
n == 0以外のケースのreturnが抜けているため、関数がstring型の値を返さずに終わりうる経路が残ります。
直し方: (空) を return "nonzero" にします。
よくある誤解
「if-elseで両方のケースを網羅していれば、コンパイラはreturnが漏れなく通ることを理解してくれるはず」という思い込みは誤りです。Goの到達可能性解析は限定的で、elseを省略したif文の外側に明示的なreturnが無いと、その関数は末尾に到達しうると判定されます。
まとめ
missing return at end of functionは初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。