処理を遅らせて実行するdefer文
defer文を使うと、処理を遅らせて関数の最後に実行させることができる。例えば、ファイルを開く処理を実行したときはファイルの使用が終わったらファイルを閉じる処理も必要になる。このようなときにファイルを開く処理とセットでdefer文でファイルを閉じる処理を書いておけばファイルの閉じ忘れが起きなくなる。
簡単な例としては
defer fmt.Println("world")
fmt.Println("Hello")
//ふつうは上から順に処理されるが、今回はworldの出力にdefer文が書かれているから以下のように出力される
Hello
world
次に、fooという関数を作り、defer文の処理を書いてmain関数から呼び出してみる。
実行してみると、foo関数の処理が先に表示される。
func foo() {
defer fmt.Println("world foo")
fmt.Println("Hello foo")
}
func main () {
foo()
defer fmt.Println("world")
fmt.Println("Hello")
}
//以下のように出力される
Hello foo
world foo
Hello
world
これは、main関数での最初にfoo関数を呼び出しており、先にHello fooを表示し、foo関数内のdefer処理のworld fooを表示させてからmain関数が処理される。
これはfoo関数の呼び出しをdefer文の下に持ってきても同様となる。
defer文が同じ階層に複数あると、、?
複数のdefer文がある場合をみてみる。
func main () {
fmt.Println("run")
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
fmt.Println("success")
}
//以下のように出力される
run
success
3
2
1
実行すると最初にrun,success、そのあとで3,2,1と表示される。最初に書いたdefer文の処理が最後に実行される。
defer文でファイルの閉じ忘れを実践する
次のコードは、ファイルの内容を読み込み、100byteを出力するコード。
func main () {
file, _ := os.Open("./lessonn.go") //lesson.goを読み込む
defer file.Close() //ファイルを閉じる(最後に実行)
data := make([]byte, 100) //要素数100のbyteのスライスを作成する
file.Read(data) //ファイルの内容を変数dataに格納する
fmt.Println(string(data)) //変数dataの内容をstring型に変換して表示する
}
//
lesson.goの最初の100byteが出力される
上記のコードの解説として、os.Open関数でファイル名を指定して読み込み、変数fileに入れる。ファイルをOpenしたら最後にcloseする必要があるのでClose処理をdefer文で記載しておく。
その後、読み込んだファイルの内容を使った処理を書いている。ファイルを読み込むときは、代入される変数をバイト配列(byteのスライス)にする必要がある。ここでは、変数dataに要素数100のbyteのスライスを入れて、ファイルの内容を100byteだけ読み込むこととする。
Readメソッドでファイルの内容を変数dataに格納した後、string型に変換して表示している。
Openした直後にCloseをdefer文で書いておけば忘れずに必須な処理を行うことができるので、安心。
学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP
・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897