Go言語 – 9.エラーハンドリング
エラー処理
JavaやC++には、try, catch, throw といったエラーを処理する構文がありますが、go言語では、関数の戻り値を複数得ることができるので、errorの判定もその都度簡単に行うことができます。
例えばこんな感じ
package main
import (
"fmt"
"os"
)
func main() {
// ファイル存在確認
fname, err := fchk("testFunction07.go")
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("ファイル名: %v\n", fname)
}
}
func fchk(filepath string) (fname string, err error) {
info, err := os.Stat(filepath)
if err == os.ErrNotExist {
fmt.Println("ファイル無し")
} else if err != nil {
fmt.Println("その他エラー")
} else {
fmt.Println("ファイル有り")
fname = info.Name()
}
return fname, err
}
エラーを無視するのも簡単です
fname, _ := fchk("testFunction07.go")
panic
ゼロ除算を行ったり、確保していない配列を参照した時等に起きる致命的なエラーが起きると強制終了しますが、この仕組みが panicです。
組み込み関数 panic を使うことで、プログラムの実行を意図して中断することができます。
package main
func main() {
testfunc()
}
func testfunc() {
panic("panic!!!")
}
結果...
panic: panic!!!
goroutine 1 [running]:
main.testfunc(...)
C:/@test/testfunction09.go:8
main.main()
C:/@test/testfunction09.go:4 +0x40
exit status 2
recover と defer を組み合わせて、panic を拾うことができます
package main
import (
"fmt"
)
func main() {
err := testfunc()
if err != nil {
fmt.Println("エラー")
fmt.Println(err)
} else {
fmt.Println("正常")
}
}
func testfunc() (err error) {
defer func() {
if rec := recover(); rec != nil {
err = fmt.Errorf("recover: %v", rec)
}
}()
testfunc1()
return
}
func testfunc1() {
fmt.Println("testfunc1 START")
testfunc2()
fmt.Println("testfunc1 END")
}
func testfunc2() {
fmt.Println("testfunc2 START")
testfunc3()
fmt.Println("testfunc2 END")
}
func testfunc3() {
fmt.Println("testfunc3 START")
panic("panic!!!")
fmt.Println("testfunc3 END")
}
結果...
testfunc1 START
testfunc2 START
testfunc3 START
エラー
recover: panic!!!
panic をゼロ除算に変えれば、ゼロ割りのランタイムエラーが見れます。
func testfunc3() {
fmt.Println("testfunc3 START")
// panic("panic!!!")
var a int
var b int
var c int
a = 10
b = 0
c = a / b
fmt.Printf("c=%v\n", c)
fmt.Println("testfunc3 END")
}
結果...
C:\@test>go run testfunction09.go
testfunc1 START
testfunc2 START
testfunc3 START
エラー
recover: runtime error: integer divide by zero






