20220127のGoに関する記事は2件です。

Goのスライスの中身がすべて同じ値になる

結論 range の左辺はただの変数である。 繰り返しのたびに再代入しているだけなので、気をつける。 現象 上手い例がかけないが、例えば以下の状況 type Foo struct { Item string } foo1 := Foo{"1"} foo2 := Foo{"2"} foo3 := Foo{"3"} slice := []Foo{foo1, foo2, foo3} var foos []*Foo for _, foo := range slice { foos = append(foos, &foo) } for _, foo := range foos { fmt.Println(foo.Item) } // => 3 // => 3 // => 3 // 中身が同じ、なぜ? なぜか中身がすべておなじになる。 原因 range の第二引数のポインタを格納してしまっているため。 詳しくは foos の中身をプリントしてみるとわかる type Foo struct { Item string } foo1 := Foo{"1"} foo2 := Foo{"2"} foo3 := Foo{"3"} slice := []Foo{foo1, foo2, foo3} var foos []*Foo for _, foo := range slice { foos = append(foos, &foo) } fmt.Println(foos) // => [0x14000010230 0x14000010230 0x14000010230] 同じポインタが3つ格納されている。 これはどこで格納されたかと言うと、 繰り返し処理のときに range の左辺の変数のポインタが格納されている。 type Foo struct { Item string } foo1 := Foo{"1"} foo2 := Foo{"2"} foo3 := Foo{"3"} slice := []Foo{foo1, foo2, foo3} var foos []*Foo for _, foo := range slice { foos = append(foos, &foo) // <= ここで変数 foo のポインタを参照し、foos に追加している } range 文で何回繰り返そうと、左辺の変数は一度のみしか定義されない(同じ変数には破壊的代入を繰り返す) そのため、ブロック内の &foo は常に同じポインタ値を返す 3回の繰り返しのうち、すべて同じポインタが格納される foos はすべて同じポインタ値を格納しているため、参照時にすべて同じ変数を見る 3回目で foo に Foo{”3”} が代入されるため、すべて Foo{"3"} を見る 対策 for ブロックの中で、左辺の変数のポインタを取得しない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLBoilerでエラー:Error: unable to initialize tables: unable to fetch table data

はじめに SQLBoilerでsqlboiler mysqlコマンドをうったときにエラーが出ました。 Go: v1.16 SQLBoiler: v4.8.3 エラー内容 Error: unable to initialize tables: unable to fetch table data: something totally unexpected happened when running the binary driver /app/go/base/sqlboiler-mysql: fork/exec /app/go/base/sqlboiler-mysql: no such file or directory 解決方法 ドライバーが入ってなかったので、 $ go get github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql でドライバーを追加したらOKでした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む