LoginSignup
3
1

More than 5 years have passed since last update.

os.Exit()はDefer functionの実行を待たない問題への対処

Last updated at Posted at 2016-06-17

Goでos.Exit()defer f()を両方使う場合を何度も調べている気がするので覚書。
おなじ関数内でこれらを使うと、deferが実行されない。別関数に分離すべき。

具体例

os.Exit()はDefer functionの実行を待たない - harukasan | Qiita
でも書かれているが

package main

import "os"

func test() {
    println("hello in test.")
}

func main() {
    println("hello in main.")
    defer test()

    println("pre-exit in main.")
    os.Exit(0)
}
/** OUTPUT **
hello in main.
pre-exit in main.  <-- defer test()が実行されていないで終わる
*/

ということが起こる。
例えばファイルのクローズなどの処理をdeferに書き、おなじ関数内でos.Exit()すると意図した終了処理が行われない。

公式ドキュメントによると、

Go言語のdeferステートメントは、deferを実行した関数がリターンする直前に、指定した関数の呼び出しが行われるようにスケジューリングします。

とのことなので、関数を分けてしまえば良い。

package main

import "os"

func test() {
    defer func() {
        println("defer in test.")
    }()
    println("hello in test.")
}

func main() {
    println("hello in main.")
    test()

    println("pre-exit in main.")
    os.Exit(0)
}
/** OUTPUT **
hello in main.
hello in test.
defer in test.
pre-exit in main.
*/

よくあるコマンドコンソールアプリの構造だと以下のような感じにする。

github.com/umanoda/hoge
├── cmd
│   └── hoge
│       └── main.go   : package main
└── hoge.go           : package hoge
github.com/umanoda/hoge/hoge.go
package hoge

type Hoge struct{
  :
}

func New() Hoge{
    h := Hoge{../* etc.. */..}
    return h
}

// errorインターフェースの実装
func (h *Hoge) Error() string{
    return "hogeeeeeeeee!!"
}

func (h *Hoge) Run() (*Hoge, error){
    /*
       : 処理
    */
    defer func(){...}() //クローズなどの処理
    // 正常終了
    return h, nil

    // 異常終了
    return h, h
}
github.com/umanoda/hoge/cmd/hoge/main.go
package main
import (
    "fmt"
    "os"
    "github.com/umanoda/hoge/hoge"
)

func main(){
    h = hoge.New()
        _, err := h.Run()
    if err != nil {
        // 異常終了
        fmt.Println("error: ", err)
        os.Exit(1)  // h.ErrorCode()を実装するとかはお好きに
    }
    os.Exit(0) // 正常終了
}

検証環境

$ go version
go version go1.6.2 linux/amd64
3
1
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
3
1