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

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

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

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

Redis

Redisは、オープンソースのkey-valueデータストアで、NoSQLに分類されます。すべてのデータをメモリ上に保存するため、処理が極めて高速です。

Q&A

2回答

2225閲覧

main関数で初期化したものをhandlerで参照するとnilになる。

Zousan

総合スコア29

Go

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

Redis

Redisは、オープンソースのkey-valueデータストアで、NoSQLに分類されます。すべてのデータをメモリ上に保存するため、処理が極めて高速です。

0グッド

0クリップ

投稿2015/08/25 01:07

現在GoでRediStoreというOSSを使用しています。そのインスタンスである*RediStoreをグローバル変数としてmain関数内で以下のとおり初期化しました。

go

1///main関数ない 2///var store *rediStore.RediStore//グローバル変数として宣言 3 store, err = redistore.NewRediStore(20, "tcp", ":6379", "", []byte("session-key")) 4 5 if store == nil { 6 //ここはnilでない 7 panic("store is nil") 8 } 9 if err != nil { 10 //エラーもない 11 panic(err) 12 } 13 defer store.Close() 14 store.SetMaxAge(259200)

そして、user_handlerというhandler内でGetSessionを呼び出すことで下記の通りそのインスタンスを参照しました。しかし、ここで参照したstoreがnilになってしまいます。main関数内でエラーがでていないので初期化は完了しているはずだと考えたのですがなぜでしょうか

go

1func GetSession(c *echo.Context) *sessions.Session { 2 if c.Request() == nil { 3 panic("c is nil") 4 } 5 if store == nil { 6 //nilになっている 7 panic("store is nil") 8 } 9 session, err := store.Get(c.Request(), KeySession) 10 if err != nil { 11 panic(err) 12 } 13 return session 14}

エラーは以下のようなものがでました。

invalid memory address or nil pointer dereference
これは自分でデバッグ用のコードを入れる前のエラーです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Go

1http.Handle("/foo", fooHandler)

みたいなコードがmainにないですが、
Handlerを呼び出すだろうコードはちゃんとその後に書いてるんですよね?
storeの初期化をinit関数に書いてみてはどうですか?

投稿2015/08/29 15:45

kokardy

総合スコア781

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

storeという変数名を見る限りパッケージプライベートな変数のため、mainパッケージ以外から書き換えられる事はあり得ません。
(書き換えを行う公開関数を用意していれば別ですが・・・)

つまり、以下のいずれかの現象が起きていると考えられます。

  1. mainパッケージ内でstore変数へ後からnilを挿入した。
  2. NewRediStoreの戻り値をグローバル変数に入れたつもりが、ローカル変数に入れていた。

前者ならば既に気付いているかと思うので、後者の可能性が高いです。
まずは以下を確認してみてはいかがでしょう。

  • main関数内でstore変数が再定義していないか
  • main関数内でstore変数への代入を=演算子でなく、:=演算子で行っている箇所は無いか

投稿2015/08/25 01:29

編集2015/08/25 01:30
hy3

総合スコア594

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zousan

2015/08/25 08:33

回答ありがとうございます。 それがどちらもあてはまらないんですよね。 第一級オブジェクトとして定義した(例えばvar store *rediStore.RediStoreなどの)変数は同じパッケージ内であればどこからでも参照できるのでしょうか。
hy3

2015/08/25 23:57

おっしゃる通り、同パッケージ内なら別ファイルであろうがどこからでも参照・代入が可能です。 store変数への代入が確実に行われているとすると、後からnilが挿入されたか、(考えにくいですが)GetSession関数がmain関数よりも先に呼ばれているということでしょうか・・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問