Go语言结构体指针

golang结构体指针

引言:在go语言中,我们如何修改一个的结构体的属性呢?

type Student struct {
	Name string
}

修改失败案例

package main

import "fmt"

//定义一个结构体 属性Name
type Student struct {
	Name string
}

//方法接收者 :即我们附加在函数名前面的参数
//类型为Student
//方法没有返回类型
func (s Student) FixNameMethod1(name string) {
	s.Name = name
}

func main() {

	s := Student{"xiaozhu"}
	fmt.Println("原有名字:", s.Name)

	
	fmt.Println("使用方法1修改名字")
	s.FixNameMethod1("xiaolan")
	fmt.Println("修改后的名字:", s.Name)

}

运行程序后我们发现案例1并没有修改成功

image-20220914213748439

分析

我们创建的s想要调用FixNameMethod1,实参是按照值传递的,所以FixNameMethod1接收到的是实参的副本,也就是s的复制品。既然是副本,那么我们在FixNameMethod1修改形参接收者的属性并不会影响到实参本身的属性

修改成功案例

package main

import "fmt"

//定义一个结构体 属性Name
type Student struct {
	Name string
}

//方法接收者参数类型为*Student
func (s *Student) FixNameMethod2(name string) {
	s.Name = name
}

func main() {

    s := Student{"xiaozhu"}
	fmt.Println("原有名字:", s.Name)

	
	fmt.Println("使用方法1修改名字")
	s.FixNameMethod1("xiaolan")
	fmt.Println("修改后的名字:", s.Name)


	fmt.Println("使用方法2修改名字")
	FixNameMethod2("lanlan")
	fmt.Println("修改后的名字:", s.Name)

}

运行程序后发现这次修改成功

image-20220914214050223

分析

我们本次方法接收者使用的参数类型是一个指向Student类型的指针,这样我们就间接的修改了实参变量

后续

但是在学习过程中 又遇到了一个新的问题

//方法接收者参数类型为*Student
func (s *Student) FixNameMethod2(name string) {
	s.Name = name
}

上述方法的方法接收者的类型是一个指向Student指针类型(*Student),而我传递给它的是一个s := Student{"xiaozhu"}, 这并不是一个指针。

那我们为什么可以修改成功呢?我又修改了一下代码加以验证

//s.FixNameMethod2("lanlan") 修改为以下代码
(&s).FixNameMethod2("lanlan")

发现名称果然可以修改成功

image-20220914214250336

分析

s.FixNameMethod2("lanlan") //相当于隐式的转化为(&s).FixNameMethod2("lanlan")

我们使用未修改前的语句时,实参接收者是Student类型的变量,形参接收者是*Student类型的变量,go的编译器会隐式的获取变量的地址, 因此我们可以修改成功

补充一点,我们上面的方法修改值的过程中,直接使用了 (s.Name = name)指针 . 属性的方式。

//方法接收者参数类型为*Student
func (s *Student) FixNameMethod2(name string) {
	s.Name = name
}

我们在c/c++当中使用的是->操作符来访问成员

举个例子

如果 him == &barney , 那么 him->income ,即是barney.income

但是在go语言中,编译器是帮我们隐式的解引用获取实际的值,因此我们完整的写下来是:

(*s).Name = name

指针Or结构体

那么我们的方法接收者的参数类型何时使用指针类型 何时使用结构体类型呢?

go语言中所有的函数参数都是值拷贝。如果结构体较大,一般使用指针参数,这样可以避免复制整个实参,并且如果要在函数修改结构体的属性,则必须使用指针参数。

再总结一下

使用指针的优点

  • 执行快,效率高
  • 可以修改数据

使用指针的缺点

  • 无法保护数据,原始数据容易修改

使用结构体的优点

  • 处理的是原始数据的副本,这样保护了原始数据
  • 代码风格非常清晰明了(更贴近于java语言)

使用结构体的缺点

  • 不能修改属性
  • 传递结构体浪费时间和空间,尤其是较大的结构体

参考书籍:《Go程序设计语言》、《C Primer Plus》
如有错误和冒犯,欢迎指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值