Golang 结构体指针方法和值方法
Posted 半梦半醒时
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang 结构体指针方法和值方法相关的知识,希望对你有一定的参考价值。
package main
import ( "fmt")
type Heap []int
func (h Heap) swap() {
h[0], h[1] = h[1], h[0]
fmt.Printf("数组 %p \\n", h)
fmt.Printf("结构体 %p \\n", &h)
h = append(h, []int{4, 5, 6}...)
fmt.Printf("扩容后数组 %p \\n", h)
fmt.Printf("扩容后结构体 %p \\n", &h)}
func main() {
arrSlice := make([]int, 5)
fmt.Printf("切片数组地址 the pointer is : %p \\n", arrSlice)
fmt.Printf("切片结构体地址 the pointer is : %p \\n", &arrSlice) //这是arrSlice本身的指针,也就是结构体的指针 printPointer(arrSlice)
a := Heap{1, 2, 3}
fmt.Printf("数组 %p \\n", a)
fmt.Printf("结构体 %p \\n", &a)
a.swap()
fmt.Println(a)}
func printPointer(any interface{}) {
fmt.Printf("传进去以后切片数组地址 the pointer is : %p \\n", any)
fmt.Printf("传进去以后切片结构体地址 the pointer is : %p \\n", &any) //打印传过来的结构体arrSlice的指针}
运行结果
▶ go run 1.go
切片数组地址 the pointer is : 0xc0000ac030
切片结构体地址 the pointer is : 0xc0000a6018
传进去以后切片数组地址 the pointer is : 0xc0000ac030
传进去以后切片结构体地址 the pointer is : 0xc000096220
数组 0xc0000b0018
结构体 0xc0000a6060
数组 0xc0000b0018
结构体 0xc0000a6090
扩容后数组 0xc0000ac090 //创建了新的底层数组扩容后结构体 0xc0000a6090 //此处为指针的拷贝,函数外的切片仍指向原数组的地址[2 1 3]
如果是用指针作为接收者,那么变量(结构体对象)本身是可以修改的,因为指针传递的是变量的地址,因此变量内部的数据可以修改。
如果用值作为接收者,那么对象内部的数据无法修改,因为用值作为接收者,在调用方法时,传递进去的是对象的副本,即使修改也只是修改副本的值,原对象的数据不会发生改变。这种可以理解为对象在该方法内是只读的。
当传入一个切片时,实际上传入的是切片的拷贝,也就是底层数组指针的拷贝。所以可以实现切片中元素位置的交换,因为交换元素不会触发扩容,不会创建新的数组。但是如果在函数内部增加切片的元素导致扩容,会创建新的底层数组,然而函数外面的指针指向的仍然是原来数组的地址,因此修改无效。
以上是关于Golang 结构体指针方法和值方法的主要内容,如果未能解决你的问题,请参考以下文章
Golang basic_leaming 指针类型和值类型实现接口的区别以及接口嵌套