読者です 読者をやめる 読者になる 読者になる

golang でどうしても文字列のポインタが欲しいとき,たいていは何か間違っているんだが,それでもポインタが必要なときもあるという釈然としない気持ち

golang Go言語

golang で文字列のポインタが欲しい! そう感じたとき,だいたい何か間違ってます. 参考:Goでxxxのポインタを取っているプログラムはだいたい全部間違っている

でも,時々どうしてもポインタが欲しくなるときがあります.

たとえば ORM ライブラリ gorm の Hstore (key=>valueが入れられる postgresql のカラム)は

type Hstore map[string]*string

と定義されていて,key=>valueの value の方を文字列のポインタで扱うようになってます.これは DB の方の value が NULL をとれたりする(空文字列じゃなくてNULLがセットできる)ので,こうなってるわけなんですが,そんなときに

a := &"Hello, World"

とやっても

cannot take the address of "Hello, World"

と怒られるのがオチです.

どうすればいいかというと,

(1)いったん変数に代入してそのアドレスを取る

tmp := "Hello, World"   
a := &tmp

(2)アドレスを返す関数を用意しておく

func toPtr(s string) *string {
    return &s
}

a := toPtr("Hello, World")

という感じです.なんか不便な感じもしますけど,string のポインタ使ってる時点で何かおかしいんで,こういうこと考えなきゃいけないときは設計を見直した方が良さそうです.

ちなみに,NULL の時もある文字列みたいなものを表現するのに,sql.NullString というものが用意されています.

type NullString struct {
        String string
        Valid  bool // Valid is true if String is not NULL
}

フラグを立てて,Valid じゃないときは NULL として扱うようになってます.gorm の Hstore も最初から map[string]sql.NullString にすればよかったんじゃないですかね・・・