LoginSignup
0
0

More than 1 year has passed since last update.

Goのdeferがよくわかならなかったので写経した

Posted at

はじめに

Go言語を最近少しずつ触っている中でdeferが出てきたのですが、調べただけでは動きがわかりづらかったので触ってみることにしました。この記事は触った記録をメモしたものです。

$ go version
go version go1.18.4 darwin/arm64

deferとは

deferはreturnされるまで実行されない書き方です。
例として以下のコードを考えます。

package main

import "fmt"

func main() {
        defer func() {
                fmt.Println("defer")
        }()
        for i := 0; i < 10; i++ {
                fmt.Println(i)
        }

}

上記のように書いた場合、defer内のfmt.Println("defer")はfor文の後に実行されます。

$ go run main.go
0
1
2
3
4
5
6
7
8
9
defer

複数のdeferを定義したときは以下のような挙動をします。

package main

import "fmt"

func main() {
        defer func() {
                fmt.Println("defer 1")
        }()
        defer func() {
                fmt.Println("defer 2")
        }()
        defer func() {
                fmt.Println("defer 3")
        }()

}

いわゆるLIFO(Last In First Out)になっていることがわかります。

$ go run main.go
defer 3
defer 2
defer 1

for文に入れて実行してみると

package main

import "fmt"

func main() {
        fmt.Println("counting")

        for i := 0; i < 10; i++ {
                defer fmt.Println(i)
        }

        fmt.Println("done")
}

後ろから順番に実行されますね。

$ go run main.go
counting
done
9
8
7
6
5
4
3
2
1
0

さいごに

deferはreturnの直前に実行される関数でした。

用途は、必要なくなったファイルを閉じたり、チャネルを閉じたり、プログラムのパニックをキャッチするために使用されるみたいです。

確かにwebsocketのコードで初めてみたのでなんとなくイメージはあっているのかもしれない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0