go语法 — 如何使用指针*和取址&

1. 如何区分指针*和取址&

指针类似于变量和常量,在使用指针前你需要声明指针。
指针声明格式如下:var name *Type
指针是指向一个值的内存地址,也就是说指针变量存放的是某个值或者对象的内存地址,即指针变量占用字节的大小与所指向的值的大小无关。当一个指针被定义后没有分配到任何变量时,它的默认值为nil。
指针变量存放的是一个值的内存地址,那如何获取一个变量的内存地址呢?那就需要使用取址符号&。
将一个值的内存地址通过&赋值给了指针,那又应该如何通过指针来读取对应的值?需要使用符号*,需要与指针声明时的*进行区别。

import (
	"fmt"
)

func main() {
	// 声明一个string数据类型的指针
	var addr *string
	var house = "Malibu Point 10880, 90265"
	// 通过&将一个变量的内存地址赋值给指针
	addr = &house
	// 通过*获取指针中存储的地址对应的值
	value := *addr
	fmt.Printf("addr type: %T\n", addr)
	// 输出指针存储的内存地址,也就是house的内存地址
	fmt.Printf("address: %p\n", addr)
	// 输出addr自身的内存地址
	fmt.Printf("address: %p\n", &addr)
	fmt.Printf("value type: %T\n", value)
	fmt.Printf("value: %s\n", value)
}
// addr type: *string
// address: 0xc000010200
// address: 0xc00000e028
// value type: string
// value: Malibu Point 10880, 90265

2. 什么情况下使用指针*和取址&

指针类型非常廉价,只占用 4 个或者 8 个字节的内存大小。

什么情况下使用指针:

  • 可以修改指向数据的值;
  • 在变量赋值,参数传值的时候可以节省内存;
  • 如果接收者类型是 map、slice、channel 这类引用类型,不使用指针;
  • 如果需要修改接收者,那么需要使用指针;
  • 如果接收者是比较大的类型,可以考虑使用指针,因为内存拷贝廉价,所以效率高。

不过 Go 语言作为一种高级语言,在指针的使用上还是比较克制的。它在设计的时候就对指针进行了诸多限制,比如指针不能进行运行,也不能获取常量的指针。以下几点使用指针的建议:

  1. 不要对 map、slice、channel 这类引用类型使用指针;
  2. 如果需要修改方法接收者内部的数据或者状态时,需要使用指针;
  3. 如果需要修改参数的值或者内部数据时,也需要使用指针类型的参数;
  4. 如果是比较大的结构体,每次参数传递或者调用方法都要内存拷贝,内存占用多,这时候可以考虑使用指针;
  5. 像 int、bool 这样的小数据类型没必要使用指针;
  6. 如果需要并发安全,则尽可能地不要使用指针,使用指针一定要保证并发安全;
  7. 指针最好不要嵌套,也就是不要使用一个指向指针的指针,虽然 Go 语言允许这么做,但是这会使你的代码变得异常复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RachelHwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值