edo1z blog

プログラミングなどに関するブログです

Go - defer conn.Close()がエラーといわれる

deferが謎です。ソケット通信のプログラムをつくってみてるんですが、色んな所に書いてある下記部分で、絶対エラーがでます。といっても実行するとエラーにならないのですが、Vimに組み込んでる、GoErrCheckがエラーといってきます。きっと何かおかしいんだと思いました。

def conn.Close()

わかりやすいサイトを見つけました。 http://www.blevesearch.com/news/Deferred-Cleanup,-Checking-Errors,-and-Potential-Problems/

GoErrCheckは、関数を使った時にリターンを受け取るように書かないとエラーをだすのですが、それのことのようです。conn.Close()は結果の成否をリータンするのでそれを受け取らなくてはいけませんでした。しかし、そうなると単純にdefer err := conn.Close()と書けなくなるので、下記のようにします。

defer func() {
  err := conn.Close()
  if err != nil {
    log.Fatal(err)
  }
}()

上記を下記のようにすると便利

conn, err := net.DialTCP("tcp", nil, tcpAddr)
defer Close(conn)

Close関数を別でつくる。

func Close(c io.Closer){
  err := c.Close()
  if err != nil {
    log.Fatal(err)
  }
}

Close関数の引数は、Closerインターフェースを持ってるやつということだと思うので、上記のconnでも使えると思う。log.Fatalはいらないケースも多いのかなと思いました。deferが呼び出された時点のconnが使われるので、複数のconnがある場合も、引数に入れることでそれぞれのconnに対応できるようになるようです。