2016-07-03 5 views
4

Goコードで遊んでいるうちに、マップ値がアドレス指定できないことがわかりました。例えば、なぜマップ値はアドレス指定できませんか?

package main 
import "fmt" 

func main(){ 
    var mymap map[int]string = make(map[int]string) 
    mymap[1] = "One" 
    var myptr *string = &mymap[1] 
    fmt.Println(*myptr) 
} 

エラー生成

mapaddressable.go:7:mymapというのアドレスを取ることができない[1]

、コード、一方

package main 
import "fmt" 

func main(){ 
    var mymap map[int]string = make(map[int]string) 
    mymap[1] = "One" 
    mystring := mymap[1] 
    var myptr *string = &mystring 
    fmt.Println(*myptr) 
} 

は完璧に動作します。

これはなぜですか? Goの開発者が特定の値を扱うことができないようにする理由は何ですか?これは欠点か言語の特徴ですか?

編集:C++背景からなので、私はゴーで流行のようです。このnot addressable傾向に慣れていないです 。次のコードは正常に動作しますたとえば、:

#include<iostream> 
#include<map> 
#include<string> 
using namespace std; 
int main(){ 
    map<int,string> mymap; 
    mymap[1] = "one"; 
    string *myptr = &mymap[1]; 
    cout<<*myptr; 
} 

同じアドレス指定が達成できない(あるいは意図的に達成されなかった)理由を誰かが行くに指摘するとよいでしょう。

+1

も参照してください。http://stackoverflow.com/questions/20224478/dereferencing-a-map-index-in-golang – nos

+1

トップの回答によれば、バケットに値を格納するハッシュテーブルです。それが再ハッシュすると、値が移動します。これを回避したい場合は、値型としてポインタを使用します。 – twotwotwo

+0

C++ 'map'sは、新しいものを追加するためにRAM内の既存のノードを動かす必要のないバイナリツリーです(しかし、O(1)ではなくO(log n)の演算平均です)。 C++の 'unordered_map'はハッシュテーブルですが、値の移動を避けるために実装に一定の制限を課す必要があります。 http://stackoverflow.com/a/31113618/2714852およびhttp://stackoverflow.com/q/37428119/を参照してください。 – twotwotwo

答えて

8

私はマップの内部Go実装についてはわかりませんが、おそらくそれは一種のハッシュテーブルです。したがって、あなたがそのエントリの1つのアドレスを取得して保存し、その後にもう1つのエントリを入れると、あなたの保存されたアドレスは無効になる可能性があります。これは、負荷率が一定のしきい値を超え、ハッシュテーブルが増加する必要がある場合のハッシュテーブルの内部再編成によるものです。
したがって、私はそのようなエラーを避けるために、そのエントリの1つのアドレスを取ることは許されないと思います。

+0

誰かが指摘した:https://github.com/golang/go/issues/11865 – weaming

関連する問題