duanpu1111
2014-12-04 02:07
浏览 32
已采纳

澄清在Go上使用等号和映射

Why does map have different behavior on Go?

All types in Go are copied by value: string, intxx, uintxx, floatxx, struct, [...]array, []slice except for map[key]value

package main

import "fmt"
type test1 map[string]int

func (t test1) DoSomething() { // doesn't need to use pointer
   t["yay"] = 1
}

type test2 []int

func (t* test2) DoSomething() { // must use pointer so changes would effect
    *t = append(*t,1)
}

type test3 struct{
    a string
    b int
}

func (t* test3) DoSomething() { // must use pointer so changes would effect
    t.a = "aaa"
    t.b = 123
}

func main() {
 t1 := test1{}
 u1 := t1
 u1.DoSomething()
 fmt.Println("u1",u1)
 fmt.Println("t1",t1)

 t2 := test2{}
 u2 := t2
 u2.DoSomething()
 fmt.Println("u2",u2)
 fmt.Println("t2",t2)

 t3 := test3{}
 u3 := t3
 u3.DoSomething()
 fmt.Println("u3",u3)
 fmt.Println("t3",t3)
}

And passing variable as function's parameter/argument is equal to assignment with :=

package main

import "fmt"
type test1 map[string]int

func DoSomething1(t test1)  { // doesn't need to use pointer
   t["yay"] = 1
}

type test2 []int

func DoSomething2(t *test2) { // must use pointer so changes would effect
    *t = append(*t,1)
}

type test3 struct{
    a string
    b int
}

func DoSomething3(t *test3) { // must use pointer so changes would effect
    t.a = "aaa"
    t.b = 123
}

func main() {
 t1 := test1{}
 DoSomething1(t1)
 fmt.Println("t1",t1)

 t2 := test2{}
 DoSomething2(&t2)
 fmt.Println("t2",t2)

 t3 := test3{}
 DoSomething3(&t3)
 fmt.Println("t3",t3)
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douqiang5163 2014-12-04 03:18
    已采纳

    Map values are pointers. Some other types (slice, string, channel, function) are, similarly, implemented with pointers. Interestingly, the linked FAQ entry says,

    Early on, maps and channels were syntactically pointers and it was impossible to declare or use a non-pointer instance. ... Eventually we decided that the strict separation of pointers and values made the language harder to use.

    "Go passes by value" means variables passed as regular function args won't be modified by the called function. That doesn't change that some built-in types can contain pointers (just like your own structs can).

    Python is similar: f(x) won't change an integer x passed to it, but it can append to a list x because Python lists are implemented with a pointer internally. C++, by contrast, has actual pass-by-reference available: f(x) can change the caller's int x if f is declared to have a reference parameter (void f(int& x)).

    (I also wrote some general info on pointers vs. values in Go in an answer to another question, if that helps.)

    点赞 评论

相关推荐 更多相似问题