質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

Goのruntime error: invalid memory address or nil pointer dereference

退会済みユーザー

退会済みユーザー

総合スコア0

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

1回答

0グッド

0クリップ

3412閲覧

投稿2021/11/06 03:19

編集2021/11/06 05:42

#runtime error: invalid memory address or nil pointer dereference
自作で簡単なAPIサーバーを作っているのですが,サーバーにリクエストを送るとTerminalに上のようなエラーが出てしまいます。解決できる方法を探しいます、よろしくお願いします。

##試したこと
GetAllBooks関数の

rows, err := db.Query("SELECT * FROM book;") if err != nil { log.Fatal(err) }

以下をコメントアウトしてリクエストを送っても、上のエラーが表示されるのですが上のコードもコメントアウトしたらブラウザーにHello worldが表示されます。なのでもしかしたら上のコードに問題があるかもしれません..

##全てのコード

Go

1package main 2 3import ( 4 "database/sql" 5 "encoding/json" 6 "fmt" 7 "github.com/go-sql-driver/mysql" 8 "github.com/gorilla/mux" 9 "log" 10 "net/http" 11 "os" 12) 13 14var db *sql.DB 15 16type Book struct { 17 ID string `json:"id"` 18 Title string `json:"title"` 19 Page int `json:"page"` 20 Price int `json:"price"` 21} 22 23type Error struct { 24 Message string `json:"message"` 25} 26 27func GetAllBooks(w http.ResponseWriter, r *http.Request){ 28 fmt.Fprintf(w, "Hello world") 29 var error Error 30 rows, err := db.Query("SELECT * FROM book;") 31 if err != nil { 32 log.Fatal(err) 33 } 34 var books []Book 35 36 if err != nil { 37 error.Message = "Cant not get data from database" 38 w.Header().Set("Content-Type", "application/json") 39 json.NewEncoder(w).Encode(error.Message) 40 return 41 } 42 43 for rows.Next() { 44 var book Book 45 if err := rows.Scan(&book.ID, &book.Title, &book.Page, &book.Price); err != nil { 46 error.Message = "Cant not get data from database" 47 w.Header().Set("Content-Type", "application/json") 48 json.NewEncoder(w).Encode(error.Message) 49 return 50 } 51 books = append(books, book) 52 } 53 if err := rows.Err(); err != nil { 54 error.Message = "Cant not get data from database" 55 w.Header().Set("Content-Type", "application/json") 56 json.NewEncoder(w).Encode(error.Message) 57 return 58 } 59 w.Header().Set("Content-Type", "application/json") 60 json.NewEncoder(w).Encode(books) 61 defer rows.Close() 62} 63 64func main(){ 65 cfg := mysql.Config{ 66 User: os.Getenv("DBUSER"), 67 Passwd: os.Getenv("DBPASS"), 68 Net: "tcp", 69 Addr: "127.0.0.1:3306", 70 DBName: "bookAPI", 71 } 72 var err error 73 db, err := sql.Open("mysql", cfg.FormatDSN()) 74 defer db.Close() 75 if err != nil { 76 log.Fatal(err) 77 } 78 pingErr := db.Ping() 79 if pingErr != nil { 80 log.Fatal(pingErr) 81 } 82 fmt.Println("Connected to database!") 83 84 router := mux.NewRouter() 85 router.HandleFunc("/books", GetAllBooks).Methods("GET") 86 log.Fatal(http.ListenAndServe(":8000", router)) 87}

#エラー内容
イメージ説明

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2021/11/06 12:14

こちらの質問が他のユーザーから「過去の低評価」という指摘を受けました。

nobonobo

2021/11/06 05:34

エラーはどの行に対して出力されましたか?
退会済みユーザー

退会済みユーザー

2021/11/06 05:43

エラー内容を見ても何行目を見ればいいのかわからないです... エラー内容の画像を追加したのでもしよければ見てください

回答1

2

ベストアンサー

エラーはなにか?

エラーはログから /usr/.../go-book-api/cmd/main.go の30行目で発生しています。

どんなエラーかというと、nil であるポインタを参照している、というエラーです。invalid memory address or nil pointer dereference から分かります。

なぜ発生しているのか?

グローバル変数として main.go の14行目に

go

1var db *sql.DB

を宣言していますが、これは初期化されていません。以下のように db 変数を初期化しているように見えますが、これは 14 行目とは別の変数として扱われています。Goの用語ではシャドーイングという仕組みによって起こっています。

go

1func main(){ 2 // ... 3 var err error 4 db, err := sql.Open("mysql", cfg.FormatDSN()) 5 defer db.Close() 6 if err != nil { 7 log.Fatal(err) 8 } 9 // ...

正しくは以下のようにすれば、想定どおり db 変数を初期化でき、nil ポインタエラーは解消されるでしょう。: の有無の違いです。

go

1func main(){ 2 // ... 3 var err error 4 db, err = sql.Open("mysql", cfg.FormatDSN()) 5 defer db.Close() 6 if err != nil { 7 log.Fatal(err) 8 } 9 // ...

投稿2021/11/06 06:19

d_tutuz

総合スコア730

melian, nobonobo👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

退会済みユーザー

退会済みユーザー

2021/11/06 06:26

実際に変えてみたらうまく動きました!本当にありがとうございます。シャドーイングについてよく調べて同じミスをしないように気をつけます!

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。