How can I store reference to the result of an oper

2019-01-06 23:34发布

Okay it's hard to describe it in words but let's say I have a map that stores int pointers, and want to store the result of an operation as another key in my hash:

m := make(map[string]*int)

m["d"] = &(*m["x"] + *m["y"])

This doesn't work and gives me the error: cannot take the address of *m["x"] & *m["y"]

Thoughts?

3条回答
乱世女痞
2楼-- · 2019-01-06 23:52

In Go, you can not take the reference of a literal value (formally known as an r-value). Try the following:

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"])
}

Have a look at this tutorial.

查看更多
Melony?
3楼-- · 2019-01-06 23:55

A pointer is a memory address. For example a variable has an address in memory.

The result of an operation like 3 + 4 does not have an address because there is no specific memory allocated for it. The result may just live in processor registers.

You have to allocate memory whose address you can put into the map. The easiest and most straightforward is to create a local variable for it.

See this example:

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"])

Output (try it on the Go Playground):

0x10438300 3

Note: If the code above is in a function, the address of the local variable (d) that we just put into the map will continue to live even if we return from the function (that is if the map is returned or created outside - e.g. a global variable). In Go it is perfectly safe to take and return the address of a local variable. The compiler will analyze the code and if the address (pointer) escapes the function, it will automatically be allocated on the heap (and not on the stack). For details see FAQ: How do I know whether a variable is allocated on the heap or the stack?

Note #2: There are other ways to create a pointer to a value (as detailed in this answer: How do I do a literal *int64 in Go?), but they are just "tricks" and are not nicer or more efficient. Using a local variable is the cleanest and recommended way.

For example this also works without creating a local variable, but it's obviously not intuitive at all:

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

Output is the same. Try it on the Go Playground.

查看更多
爷、活的狠高调
4楼-- · 2019-01-07 00:09

The result of the addition is placed somewhere transient (on the stack) and it would therefore not be safe to take its address. You should be able to work around this by explicitly allocating an int on the heap to hold your result:

result := make(int)
*result = *m["x"] + *m["y"]
m["d"] = result
查看更多
登录 后发表回答