見出し画像

Shizuoka.go Vol.14に参加しました。

7/20に静岡市でGo langの勉強会がありましたので、参加してきました。今回で14回目だそうです。私ははじめての参加。

人数は私を含めて5名と少なめ。。。

Go langについて

私がGo langの勉強会に参加しようと思ったのは、以下の理由です。
・会社のプロジェクトで使うかもしれない
・なんか流行ってる
この時点で、Go langに対して強い思いがあったわけではないです。

この日の主な内容は以下の3つ
・エラー
・並行処理
・フレームワーク/ライブラリ

ここでは、Go langのエラーについて書きます。
並行処理については別途書きます。

エラー

Go langにはTry-Catchの仕組みがありません。
そのため、関数の呼び出し元にエラーを通知するには、エラーの情報を関数の復帰値として返す必要があります。
Goのエラーとは、以下のInterfaceに該当するものです。
単にエラーメッセージを返す関数があるだけです。

// cf. https://golang.org/pkg/builtin/#error
type error interface {
 Error() string
}

上記の方法では、関数の呼び出しがネストしている場合、エラーの原因となった最初のエラーの情報を通知したいといった場合に困ります。
fmt.Errorfでもとのエラーの情報を埋め込むと言った方法があるようですが、文字列に情報を埋め込むだけのようなので、もとのエラーが何かを判定することができません。

この問題は、golang.org/x/xerrorsを利用することで解決できます。これを利用すると原因となったエラーの情報を上位に通知することができます。Go lang 1.13では、標準パッケージに含まれます。(移行作業が必要)

・埋め込み

func Errorf(format string, a ...interface{}) error


・取り出し

func Unwrap(err error) error

Sample Code

package main

import(
	"bufio"
	"fmt"
	"io"
	"os"
	"golang.org/x/xerrors"
)

func main() {
	err := readFile("notfound")
	if err != nil {
		fmt.Printf("wraped\n %v\n", err)
		fmt.Println("-----------------")
		fmt.Printf("unwraped\n %v\n", xerrors.Unwrap(err))
		fmt.Println("-----------------")
		fmt.Printf("stack\n %+v\n", err)
		fmt.Println("-----------------")
	}
}

func readFile(filename string) error {
	fp, err := os.Open(filename)
	if err != nil {
		return xerrors.Errorf("Can not open file.: %w", err)
	}
	defer fp.Close()

	reader := bufio.NewReaderSize(fp, 4096)
	for line := ""; err == nil; line, err = reader.ReadString('\n') {
		fmt.Print(line)
	}

	if err != io.EOF {
		return xerrors.Errorf("Can not read file: %w", err)
	} else {
		return nil
	}
}

これって、どこかで聞いたような話のような気がしませんか?
JavaにはThrowable.getCauseという、原因となったエラーを取得するメソッドがあります。このメソッドは、1.4で追加されており、1.3以前はありませんでした。そのため、原因となるエラーを埋め込めるように自分で拡張していました。
歴史は繰り返す。。。そのうち、Genericsも追加されるのでしょうね。(GenericsはGo 2で追加決定?。末尾再帰の最適化もやってほしい。)

また、xerrorsを使うことでスタックトレースも表示されるようです。
スタックトレースがでないと、エラー発生時の調査に支障がでるので、現時点ではxerrorsは必須ですね。

fmt.Printf("stack\n %+v\n", err)

実行結果

stack
Can not open file.:
   main.readFile
       /go/src/github.com/your-github-account/hello/helloworld.go:26
 - open notfound: no such file or directory

感想

Go langは言語仕様は単純なので、理解しやすい言語だと感じました。(みなさんそう話しているかと思います)
単純な分、面白みはないかなと。
ただ、仕事としては今後増えていくと思いますので、引き続き勉強していきたいと思います。

おまけ

懇親会終了後に久しぶりにおでん横丁に行きました。
静岡おでん最高!


この記事が気に入ったらサポートをしてみませんか?