はじめに
以下のようなコードで、err != nil
のとき、
ある関数ではmodels.Article{}
と空の構造体を返しているのに対し、
func PostArticleService(article models.Article) (models.Article, error) {
// 略
newArticle, err := repositories.InsertArticle(db, article)
if err != nil {
return models.Article{}, err
}
return newArticle, err
}
別の関数では(空のスライス[]models.Article{}
ではなく)nil
を返しています。
func GetArticleListService(page int) ([]models.Article, error) {
// 略
articleList, err := repositories.SelectArticleList(db, page)
if err != nil {
return nil, err
}
return articleList, err
}
この相違点がなぜ生まれるのか気になり、調べました。
空の構造体を返す場合
まず、1つ目の関数ではなぜnilではなく空の構造体を返しているのかを考えます
nilについては以下のように説明されています。
nil(ニル)はGoで事前に定義された識別子で、ポインタ、インターフェイス、マップ、スライス、チャネル、関数型などのゼロ値を表します。
つまり、nilは参照型のゼロ値を表すのに使うものであり、値型である構造体のゼロ値は表せないようです。
したがって、構造体のゼロ値を表すには、models.Article{}
のように表記するしかありません。
func PostArticleService(article models.Article) (models.Article, error) {
// 略
newArticle, err := repositories.InsertArticle(db, article)
if err != nil {
return models.Article{}, err
}
return newArticle, err
}
nilを返す場合
上記の通りnilは参照型のゼロ値を表すのに使うものなので、返り値の型がスライスならnilを返します。
func GetArticleListService(page int) ([]models.Article, error) {
// 略
articleList, err := repositories.SelectArticleList(db, page)
if err != nil {
return nil, err
}
return articleList, err
}
ちなみに、空のスライス[]models.Article{}
を返してもエラーにはなりませんが、そうするとエラーではなくデータが存在しないことを表すので、エラーの有無がわかりにくくなってしまい、推奨されないようです。
おわりに
ふと気になって調べたのですが、Goの理解が深まりました。