参考:
https://blog.csdn.net/weixin_44282540/article/details/95367012
关键词
- 变量、指针变量、取地址符、取值的关系
- 什么场景下使用指针
- 什么场景下不使用指针
ptr := &v // v 的类型为 T
fmt.Printf("%v", *ptr)
其中,
- v 表示 变量,类型假设是T,
- & 取地址符
- &v 表示 取变量v的地址
- ptr 表示 指针变量,类型是*T
1、变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
对变量进行取地址(&)操作,可以获得这个变量的指针变量。
指针变量的值是指针地址。
对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。
变量、指针和地址三者的关系是
每个变量
都拥有地址
,指针的值
就是地址
。
2、什么场景下使用指针
如果该函数会修改receiver,此时一定要用指针
如果receiver是 struct 并且包含互斥类型 sync.Mutex ,或者是类似的同步变量,receiver必须是指针,这样可以避免对象拷贝
如果receiver是较大的 struct 或者 array ,使用指针则更加高效。多大才算大?假设struct内所有成员都要作为函数变量传进去,如果觉得这时数据太多,就是struct太大
如果receiver是 struct , array 或者 slice ,并且其中某个element指向了某个可变量,则这个时候receiver选指针会使代码的意图更加明显
3、什么场景下 不用指针呢?
如果receiver是 map 、 func 或者 channel ,不要使用指针
如果receiver是 slice 并且该函数并不会修改此slice,不要使用指针
如果receiver使较小的 struct 或者 array ,并且其变量都是些不变量、常量,例如 time.Time ,value receiver更加适合,因为value receiver可以减少需要回收的垃圾量。
package main
import (
"fmt"
)
func main() {
// 准备一个字符串类型
var house = "Malibu Point 10880, 90265"
// 对字符串取地址, ptr类型为*string
ptr := &house
// 打印ptr的类型
fmt.Printf("ptr type: %T\n", ptr)
// 打印ptr的指针地址
fmt.Printf("address: %p\n", ptr)
// 对指针进行取值操作
value := *ptr
// 取值后的类型
fmt.Printf("value type: %T\n", value)
// 指针取值后就是指向变量的值
fmt.Printf("value: %s\n", value)
}