0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的備忘録:Goアプリで発生した「db.NewDB() (no value) used as value」エラーの原因と解決方法

Last updated at Posted at 2025-02-19

はじめに

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 の戻り値を追加する方法もある。

このエラーに遭遇したら、「関数の戻り値があるかどうか」を確認し、適切な方法で修正してみてください。

0
1
1

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?