要实现一个这样的函数 GetOne
:
func main() {
var oi OrderInfo
GetOne(&oi)
fmt.Println(oi)
}
type OrderInfo struct {
Id string
Price float64
Status int
}
func GetOne(orderInfo *OrderInfo) {
}
传入一个指针作为 GetOne
的参数,然后在函数内给这个指针变量设置值。
正确的写法应该是这样的:
func GetOne(orderInfo *OrderInfo) {
*orderInfo = OrderInfo{
Id: "aaaa",
Price: 100.00,
Status: 1,
}
}
错误的写法,oi
变量是空值:
func GetOne(orderInfo *OrderInfo) {
orderInfo = &OrderInfo{
Id: "aaaa",
Price: 100.00,
Status: 1,
}
}
其实一个很好的判断标准就是传入的地址和传出的地址是否发生变化,如果地址不一样了,那自然就无法给它赋值了。
// 传入
fmt.Printf("%p\n", &oi) // 0xc0000044a0
// 方法一
*orderInfo = OrderInfo{
Id: "aaaa",
Price: 100.00,
Status: 1,
}
fmt.Printf("%p\n", orderInfo) // 0xc0000044a0
fmt.Println(orderInfo) // &{aaaa 100 1}
// 方法二
orderInfo = &OrderInfo{
Id: "aaaa",
Price: 100.00,
Status: 1,
}
fmt.Printf("%p\n", orderInfo) // 0xc0000044e0
fmt.Println(orderInfo) // &{aaaa 100 1}
可见方法二的 orderInfo
地址发生了变化,因此无法给引用赋值。
形参 orderInfo
存储的是一个地址p
,而 *orderInfo
表示访问p
指向的内存中的值,改变这个值就改变了实参的实际内容,达到了赋值的效果。但是方法二是改变了 orderInfo
的值,于是它指向了一个新的地址,就和实参没什么关系了。