2015-12-10 15 views
6

オーケー、それは言葉でそれを説明したがのが、私はintポインタを保存するマップを持っているとしましょう、と私のハッシュで他のキーなどの操作の結果を保存するのは難しいです私にエラーを与える:cannot take the address of *m["x"] & *m["y"]Goの操作結果への参照はどのように保存できますか?</p> <pre><code>m := make(map[string]*int) m["d"] = &(*m["x"] + *m["y"]) </code></pre> <p>これは動作しません:

思考?

+0

なぜこのようなものを保存したいですか? 'm [" d "] = m [" x "] + m [" y "]'は演算の結果を格納します – fabrizioM

答えて

10

ポインタはメモリアドレスです。たとえば、変数にはメモリ内のアドレスがあります。

3 + 4のような操作の結果には、特定のメモリが割り当てられていないため、アドレスがありません。結果は単にプロセッサレジスタに存在するかもしれません。

アドレスをマップに配置できるメモリを割り当てる必要があります。最も簡単で簡単な方法は、ローカル変数を作成することです。

この例を参照してください:

x, y := 1, 2 
m := map[string]*int{"x": &x, "y": &y} 

d := *m["x"] + *m["y"] 
m["d"] = &d 

fmt.Println(m["d"], *m["d"]) 

出力(Go Playground上でそれを試してみてください):

0x10438300 3 

注:上記のコードは、関数内のローカル変数のアドレスである場合(d)は、関数から戻ってきても(つまり、グローバル変数などの外部に返された、または作成された場合でも)生き続けます。 Goでは、ローカル変数のアドレスを取得して返すのが完全に安全です。コンパイラはコードを解析し、アドレス(ポインタ)が関数をエスケープすると、自動的にヒープ上に(スタック上ではなく)割り当てられます。詳細は、参照してくださいFAQ: How do I know whether a variable is allocated on the heap or the stack?

ノート#2:あり(この答えに詳述:How do I do a literal *int64 in Go?)値へのポインタを作成するための他の方法がありますが、それらは単に「トリック」であり、ないよりよいまたはより効率的です。ローカル変数を使用するのが最もクリーンで推奨される方法です。例えば

これは、ローカル変数を作成せずに動作しますが、それは全く明らかに直感的ではありません。

m["d"] = &[]int{*m["x"] + *m["y"]}[0] 

出力は同じです。 Go Playgroundで試してみてください。

0

加算の結果は(スタック上に)一時的な場所に配置されるため、そのアドレスをとることは安全ではありません。

ゴーで
result := make(int) 
*result = *m["x"] + *m["y"] 
m["d"] = result 
0

、あなたは(正式にはr値として知られている)リテラル値の参照を取ることはできません:あなたは、あなたの結果を保持するために、明示的にヒープ上intを割り当てることによってこの問題を回避することができるはずです。 Try

package main 

import "fmt" 

func main() { 

    x := 3; 
    y := 2; 
    m := make(map[string]*int) 

    m["x"] = &x 
    m["y"] = &y 

    f := *m["x"] + *m["y"] 
    m["d"] = &f 

    fmt.Printf("Result: %d\n",*m["d"]) 
} 

thisチュートリアルを見てください。