本文已参与「新人创作礼」活动,一起开启掘金创作之路。
首先来回顾一下,什么是指针,什么是引用,什么是地址
指针是代表内存中存储值的位置,而不是值本身。 在golang中,(它们指向别的东西)通过使用指针(*int),zero函数能够修改原始变量。
引用是什么? 存放pointer的变量,引用本身有一个另外的指针地址。
什么是地址? 我之前给本科生上课常用的一个例子,就是用一本书来做比喻。页码就是地址,页码对应的那一页书上的内容就是存放的值。
以上的概念,实际上对于任何语言都是一样的,所以只要理解了上面的概念,在面对任何一门语言的时候,需要学习的只是:上面的概念,该语言是如何来表示,如何来实现,如何来使用的。
例子
大家先看一段简短代码就很明白了。重点是 函数的入参 函数的返回
type Foo struct {
Name string
}
func change(foo Foo) Foo {
foo.Name = "changed"
return foo
}
func changePointer(foo *Foo) Foo {
foo.Name = "changed"
log.Printf("change1 Name: %s,change pointer: %p", foo.Name, foo)
log.Printf("change2 Name: %s,change pointer: %p", foo.Name, &*foo)
return *foo
}
func pointerTest() {
foo := Foo{Name: "test", Age: 123}
log.Printf("foo Name: %s,foo pointer: %p", foo.Name, &foo)
fooo := change(foo)
log.Printf("fooo Name: %s,fooo pointer: %p", fooo.Name, &fooo)
log.Printf("foo Name: %s,foo pointer: %p", foo.Name, &foo)
foooo := changePointer(&foo)
foooo.Name = "final"
log.Printf("foooo Name: %s,foooo pointer: %p", foooo.Name, &foooo)
log.Printf("foo Name: %s,foo pointer: %p", foo.Name, &foo)
}
func main() {
pointerTest()
}
输出如下:
2019-08-16 15:54:07.400133 I | foo Name: test,foo pointer: 0xc000170120
2019-08-16 15:54:07.400296 I | fooo Name: changed,fooo pointer: 0xc000106cc0
2019-08-16 15:54:07.400302 I | foo Name: test,foo pointer: 0xc000170120
2019-08-16 15:54:07.400308 I | change1 Name: changed,change pointer: 0xc000170120
2019-08-16 15:54:07.400312 I | change2 Name: changed,change pointer: 0xc000170120
2019-08-16 15:54:07.400317 I | foooo Name: final,foooo pointer: 0xc000106ce0
2019-08-16 15:54:07.400321 I | foo Name: changed,foo pointer: 0xc000170120
大家看完这段代码,就都懂了哦。
重点:
参数是值拷贝,函数返回也是值拷贝。
TODO:对基本类型来说,正常情况下是不需要考虑用指针的。等下我再加入这部分。