英文:
Clarification on using equal sign and map on Go
问题
为什么在Go语言中map
的行为不同?
Go语言中的所有类型都是按值传递的:string
、intxx
、uintxx
、floatxx
、struct
、[...]array
、[]slice
,除了map[key]value
。
并且,将变量作为函数的参数传递等同于使用:=
进行赋值。
以下是代码的翻译:
package main
import "fmt"
type test1 map[string]int
func (t test1) DoSomething() { // 不需要使用指针
t["yay"] = 1
}
type test2 []int
func (t *test2) DoSomething() { // 必须使用指针以便修改生效
*t = append(*t, 1)
}
type test3 struct {
a string
b int
}
func (t *test3) DoSomething() { // 必须使用指针以便修改生效
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)
}
package main
import "fmt"
type test1 map[string]int
func DoSomething1(t test1) { // 不需要使用指针
t["yay"] = 1
}
type test2 []int
func DoSomething2(t *test2) { // 必须使用指针以便修改生效
*t = append(*t, 1)
}
type test3 struct {
a string
b int
}
func DoSomething3(t *test3) { // 必须使用指针以便修改生效
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)
}
希望对你有帮助!
英文:
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
得分: 3
值为指针的映射。一些其他类型(切片、字符串、通道、函数)也是通过指针实现的。有趣的是,链接的常见问题解答中提到:
> 早期,映射和通道在语法上是指针,无法声明或使用非指针实例。... 最终,我们决定严格区分指针和值会使语言更难使用。
“Go按值传递”意味着作为常规函数参数传递的变量不会被调用函数修改。这并不改变一些内置类型可以包含指针的事实(就像你自己的结构体一样)。
Python也是类似的:f(x)
不会改变传递给它的整数x
,但它可以向列表x
追加元素,因为Python列表在内部是通过指针实现的。相比之下,C++实际上提供了传引用的方式:如果f
被声明为具有引用参数(void f(int& x)
),则f(x)
可以更改调用者的int x
。
(我还在回答另一个问题时写了一些关于Go中指针与值的一般信息,如果有帮助的话。)
英文:
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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论