乐趣区

关于golang:你知道-Go-结构体和结构体指针调用有什么区别吗

微信搜寻【脑子进煎鱼了】关注这一只爆肝煎鱼。本文 GitHub github.com/eddycjy/blog 已收录,有我的系列文章、材料和开源 Go 图书。

大家好,我是煎鱼。

前几天在分享《Go 构造体是否能够比拟,为什么?》时,有小伙伴提出了新的问题:

尽管大家提问题的速度曾经超出了本鱼写文章的速度 … 不过作为宠粉狂鱼,在此刻清明假期时还是写下了这篇文章。

我在网上冲浪时搜寻了相干问题,发现 6 年前就有 Go 开发者有截然不同的疑难,真是困扰了一代又一代的小伙伴。

本期的男主角是《Go 构造体和构造体指针调用有什么区别》,心愿对大家有所帮忙,带来一些思考。

请在此处默念本人心目中的答案,再和煎鱼一起研究一波 Go 的技术哲学。

构造体是什么

在 Go 语言中有个根本类型,开发者们称之为构造体(struct)。是 Go 语言中十分罕用的,根本定义:

type struct_variable_type struct {
    member definition
    member definition
    ...
    member definition
}

简略示例:

package main

import "fmt"

type Vertex struct {
    Name1 string
    Name2 string
}

func main() {v := Vertex{"脑子进了", "煎鱼"}
    v.Name2 = "蒸鱼"
    fmt.Println(v.Name2)
}

输入后果:

蒸鱼

这部分属于基础知识,因而不再过多解释。如果看不懂,倡议重学 Go 语言语法根底。

构造体和指针调用

解说前置概要后,间接进入本文主题。如下例子:

type MyStruct struct {Name string}

func (s MyStruct) SetName1(name string) {s.Name = name}

func (s *MyStruct) SetName2(name string) {s.Name = name}

该程序申明了一个 User 构造体,其蕴含两个构造体办法,别离是 SetName1SetName2 办法,两者之间的差别就是 援用的形式不同

进一步延长,这两者有什么区别,什么状况下用哪种,有没有什么注意事项?

注:很巧,我有一个敌人,当年刚上手 Go 语言时,就纠结过这个问题。

两者区别

从许多小伙伴的反馈来看,这两个例子之间的区别可能会让人感到困惑,常常会有人纠结要不要应用“指针”,又放心 GC 什么的。

实际上状况没那么简单,看看上面的例子:

func (s MyStruct) SetName1(name string) 
func (s *MyStruct) SetName2(name string)

当在一个类型上定义一个办法时,接收器(在下面的例子中是 s)的行为就像它是办法的一个参数一样。其相当于:

 func SetName1(s MyStruct, name string){u.Name = name}

 func SetName2(s *MyStruct,name string){u.Name = name}

因而构造体办法是要将接收器定义成值,还是指针。这实质上与函数参数应该是值还是指针是同一个问题。

如何抉择

整体有以下几个思考因素,按重要水平顺序排列:

  1. 在应用上的思考:办法是否须要批改接收器?如果须要,接收器必须是一个指针。
  2. 在效率上的思考:如果接收器很大,比方:一个大的构造体,应用指针接收器会好很多。
  3. 在一致性上的思考:如果类型的某些办法必须有指针接收器,那么其余的办法也应该有指针接收器,所以无论类型如何应用,办法集都是统一的。

回到下面的例子中,从性能应用角度来看:

  • 如果 SetName2 办法批改了 s 的字段,调用者是能够看到这些字段值变更的,因为其是指针援用,实质上是同一份。
  • 绝对 SetName1 办法来讲,该办法是用调用者参数的副原本调用的,实质上是值传递,它所做的任何字段变更对调用者来说是看不见的。

另外对于根本类型、切片和小构造等类型,值接收器是十分便宜的。

因而除非办法的语义须要指针,那么值接收器是最高效和清晰的。在 GC 方面,也不须要适度关注。呈现时再解决就好了。

总结

在本文中,咱们针对 Go 构造体和构造体指针调用有什么区别,这个问题进行了深入浅出的剖析和阐明。

而在本文中所介绍的局部内容,来自于官网 FAQ 的“Should I define methods on values or pointers?”,能够认为是官网给出的根本解答了(问的人是真的多)。

谁纳闷这个问题,转发这篇文章,吸就完了。

若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,回复【000】有我筹备的一线大厂面试算法题解和材料;本文 GitHub github.com/eddycjy/blog 已收录,欢送 Star 催更。

退出移动版