はじめに
Go で開発を進めていると、関数の戻り値に関するエラーに遭遇することがあります。その中でも、(no value) used as value
というエラーは、関数の戻り値を期待しているのに実際には何も返していない場合 に発生します。
本記事では、ECS 環境で Go アプリをデプロイした際に発生した db.NewDB()
に関するエラー について、原因と解決策を整理しました。
エラー内容
Goのプログラムをビルドまたは実行すると、以下のようなエラーが発生することがあります。
router/router.go:19:8: db.NewDB() (no value) used as value
このエラーは、Goの関数 db.NewDB()
の戻り値がないのに、戻り値を使おうとした場合に発生します。
エラーの発生原因
エラーの原因は、NewDB()
関数の定義と、それを呼び出す側 (router.go
など) のコードの不整合です。
誤ったコード
db.go
package db
import (
"fmt"
"log"
"os"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB // グローバルな DB 変数
func NewDB() { // ← 戻り値がない
url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True",
os.Getenv("MYSQL_USER"),
os.Getenv("MYSQL_PW"),
os.Getenv("MYSQL_HOST"),
os.Getenv("MYSQL_PORT"),
os.Getenv("MYSQL_DB"))
var err error
DB, err = gorm.Open(mysql.Open(url), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected")
}
router.go
package router
import (
"skill-typing-back/db"
)
func SetupRouter() {
dbInstance := db.NewDB() // エラー発生! NewDB() に戻り値がないのに受け取っている
}
このように、NewDB()
は *gorm.DB
を返さないのに、dbInstance := db.NewDB()
で戻り値を受け取ろうとするとエラーになります。
解決方法
方法 1: router.go
の呼び出しを修正
最も簡単な修正方法は、NewDB()
の戻り値を受け取らないようにすることです。
修正後の router.go
package router
import (
"skill-typing-back/db"
)
func SetupRouter() {
db.NewDB() // 戻り値を受け取らずに実行
}
これで、戻り値を期待しない形になるため、エラーが解消されます。
方法 2: NewDB()
に戻り値を追加
もし NewDB()
の戻り値を使いたい場合は、関数の定義を修正して戻り値 *gorm.DB
を追加する方法もあります。
修正後の db.go
func NewDB() *gorm.DB { // 戻り値を追加
url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True",
os.Getenv("MYSQL_USER"),
os.Getenv("MYSQL_PW"),
os.Getenv("MYSQL_HOST"),
os.Getenv("MYSQL_PORT"),
os.Getenv("MYSQL_DB"))
db, err := gorm.Open(mysql.Open(url), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected")
return db // DB インスタンスを返す
}
修正後の router.go
package router
import (
"skill-typing-back/db"
)
func SetupRouter() *echo.Echo {
e := echo.New()
// DBコネクション作成(戻り値を受け取らずに実行)
db.NewDB()
// DBリポジトリ初期化(db.GetDB() を使う)
repo := repository.New(db.GetDB())
・・・
・・・
}
この方法を使えば、NewDB()
の戻り値を DBコネクションとして利用できるようになります。
どちらの方法を選ぶべきか?
方法 | 適用ケース | メリット |
---|---|---|
方法 1: NewDB() の戻り値を受け取らない |
グローバル変数 DB を利用する |
修正が簡単・コードがシンプル |
方法 2: NewDB() に戻り値を追加する |
DBコネクションを明示的に取得・管理したい | 柔軟なDB管理が可能 |
基本的には、方法 1 の修正(戻り値を受け取らない)で十分ですが、NewDB()
の戻り値を明示的に使いたい場合は 方法 2 を選ぶとよいでしょう。
まとめ
-
"(no value) used as value"
エラーは、関数の戻り値がないのに受け取ろうとすると発生する。 - 最も簡単な修正方法は、
db.NewDB()
の戻り値を受け取らないようにすること。 - より柔軟にするなら、
NewDB()
に*gorm.DB
の戻り値を追加する方法もある。
このエラーに遭遇したら、「関数の戻り値があるかどうか」を確認し、適切な方法で修正してみてください。