GO中的 & 和 * 在创建结构体对象场景中的含义

在赋值场景中 & 和 *  分别是取地址和取值的两个特殊操作,是最基础的用法和语义。

当 * 出现在参数中或者声明场景时,代表传参类型需要指针类型或者声明一个指针变量。

基本类型的应用场景:

a := 1 // 声明变量a 并赋值1
var b *int // 声明int类型地址指针 变量b
b = &a // 将a变量地址赋值给 地址指针 b
c := *b // c取值*b,也就是 *&a 得到的就是 变量a的值 1  *&a = a, 相当于*&抵消了
 
// 上述场景为通常的变量取地址和取值

struct结构体对象应用场景:

import (
	"fmt"
)

type Book struct { // 定义一个Book类型的结构体,有三个导出(public访问权限)属性
    ID int64
    Title string
    Price float32
}

// 定义两个函数,一个是传递Book值参数,一个是传递Book指针参数
// 作为值传递的参数Book,在方法体内使用参数b时,不会改变原对象
func changePrice1(b Book, p float32) {
	b.Price = p
}

// 作为指针传递的参数Book,在方法体内使用参数b时,会改变原对象
func changePrice2(b *Book, p float32) {
	b.Price = p
}


func main() {
    // 方式1创建并赋值, 此时创建b1是一个值对象,直接使用b1时作为值对象使用,如果作为指针需要使用&
    b1 := Book{1, "go", 12.1}

    // 方式2创建并赋值,此时创建b2是一个指针对象,直接使用b2时作为指针使用,如果要获取对象值使用*
    b2 := &Book{2, "java", 1.1}

    // changePrice1需要的Book参数为值对象所以此时当前main作用域内的b1和b2的字段值不会改变
    changePrice1(b1, 10)
    changePrice1(*b2, 10)

    // 打印的b1 b2的Price值为原值,并且可以注意到,打印的b1为{...}, b2为&{...}
    fmt.Println(b1) 
    fmt.Println(b2)

    // changePrice2需要的Book参数为指针对象所以此时当前main作用域内的b1和b2的字段值会改变
    changePrice2(&b1, 10)
    changePrice2(b2, 10)
    
    // b1 b2的Price变为了10
    fmt.Println(b1) 
    fmt.Println(b2)

}

该场景下可以看出,创建对象时,直接创建type_name{}和&type_name{}的区别,如果需要当前对象在多数情况下作为指针使用并传递时使用&type_name{}方式创建对后续使用更方便,如果只作为dto类型的值使用时,直接type_name{}方式创建和使用更方便。

两种形式的创建对象都可以,具体使用哪种要参照业务场景,选择一个合适的即可。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值