LoginSignup
1
1

More than 5 years have passed since last update.

golangの配列/連想配列で困ったこと

Posted at

jsonbaseとか言うjsonを簡単に扱うためのライブラリを自作しましたが、配列と連想配列を同じ様に扱ったら困ったので書きます。

結論からいうと、アドレスの取り出しの可否という違いがありました。

サンプル

配列

ar := []int{10, 20, 30}
mp := map[int]int{0: 10, 1: 20, 2: 30}

機能的には同一のものを用意。

そこからポインタを取り出す。

ar := []int{10, 20, 30}
arp := &ar[0]
*arp++
fmt.Println(arr) // [11 20 30]

普通ですね。
配列の要素のポインタを取り出して値を書き換えると、配列の要素が書き換わります。

連想配列

次に連想配列です。

mp := map[int]int{0: 10, 1: 20, 2: 30}
arp := &mp[0]
*arp++
fmt.Println(mp) // tmp/sandbox429707758/main.go:7: cannot take the address of mp[0]

結果がエラーになりました。
Map(連想配列)からはアドレスを取り出せないみたいです。

エラーが起きないように調整

mp := map[int]int{0: 10, 1: 20, 2: 30}
arp := mp[0]
arp++
fmt.Println(mp) // map[0:10 1:20 2:30]

当たり前ですが、無意味でした。
いろいろ試しましたが、連想配列では値コピーでしか値を取り出せないため、アドレスを取得することができませんでした。

最初からアドレスを格納すれば?という話ですが、自作のjsonbaseはencoding/jsonパッケージを使っているので自動的に値として連想配列に格納されます。

まとめ

この仕様がなければ、jsonbaseでSetやGetのたびに再帰的にたどるのではなく、子要素をたどるたびにそのポインタを取り出して操作するという非常に単純なものにできました。
連想配列の仕組み的にこうするしかなかったんでしょうかね。

再帰的に連想配列の値を取得して、その値をポインタ変数の値として格納しなおした新しい連想配列を返す、みたいなライブラリがどこかにないかな...とか思ったりしています。
reflect必須ですね。

1
1
0

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