type Bag struct {
items []int
}
func Insert(b *Bag, itemId int) {
b.items = append(b.items, itemId)
}
func main() {
bag :=new(Bag)
Insert(bag,1001)
}
代码说明如下:
- 第 3 行,声明 Bag 结构,这个结构体包含一个整型切片类型的 items 的成员。
- 第 7 行,定义了 Insert() 函数,这个函数拥有两个参数,第一个是背包指针(*Bag),第二个是物品 ID(itemid)。
- 第 8 行,用 append() 将 itemid 添加到 Bag 的 items 成员中,模拟往背包添加物品的过程。
- 第 12 行,创建背包实例 bag。
- 第 13 行,调用 Insert() 函数,第一个参数放入背包,第二个参数放入物品 ID。
Insert() 函数将 *Bag 参数放在第一位,强调 Insert 会操作 *Bag 结构体,但实际使用中,并不是每个人都会习惯将操作对象放在首位,一定程度上让代码失去一些范式和描述性。同时,Insert() 函数也与 Bag 没有任何归属概念,随着类似 Insert() 的函数越来越多,面向过程的代码描述对象方法概念会越来越麻烦和难以理解。
3.1.2 Go语言的结构体方法
将背包及放入背包的物品中使用Go语言的结构体和方法方式编写,为 *Bag 创建一个方法,代码如下:
package main
type Bag struct {
items []int
}
func (b *Bag) Insert(itemId int) {
b.items = append(b.items, itemId)
}
func main() {
bag := new(Bag)
bag.Insert(1001)
}
第 7 行中,Insert(itemid int) 的写法与函数一致,(b*Bag) 表示接收器,即 Insert 作用的对象实例。
第 13 行中,在 Insert() 转换为方法后,我们就可以愉快地像其他语言一样,用面向对象的方法来调用 b 的 Insert。
每个方法只能有一个接收器,如下图所示。
3.2 接收器——方法作用的目标
接收器的格式如下:
func (接收器变量 接收器类型) 方法名(参数列表) (返回参数) {
函数体
}
对各部分的说明:
- 接收器变量:接收器中的参数变量名在命名时,官方建议使用接收器类型名的第一个小写字母,而不是 self、this 之类的命名。例如,Socket 类型的接收器变量应该命名为 s,Connector 类型的接收器变量应该命名为 c 等。
- 接收器类型:接收器类型和参数类似,可以是指针类型和非指针类型。
- 方法名、参数列表、返回参数:格式与函数定义一致。
接收器根据接收器的类型可以分为指针接收器
、非指针接收器
,两种接收器在使用时会产生不同的效果,根据效果的不同,两种接收器会被用于不同性能和功能要求的代码中。
3.2.1 理解指针类型的接收器
指针类型的接收器由一个结构体的指针组成,更接近于面向对象中的 this 或者 self。
由于指针的特性,调用方法时,修改接收器指针的任意成员变量,在方法结束后,修改都是有效的
。
在下面的例子,使用结构体定义一个属性(Property),为属性添加 SetValue() 方法以封装设置属性的过程,通过属性的 Value() 方法可以重新获得属性的数值,使用属性时,通过 SetValue() 方法的调用,可以达成修改属性值的效果。
package main
import “fmt”
// 定义属性结构
type Property struct {
value int // 属性值
}
// 设置属性值
func (p *Property) SetValue(v int) {
// 修改p的成员变量
p.value = v
}
// 取属性值
func (p *Property) Value() int {
return p.value
}
func main() {
// 实例化属性
p := new(Property)
// 设置值
p.SetValue(100)
// 打印值
fmt.Println(p.Value())
}
运行程序,输出如下:
100
代码说明如下:
- 第 6 行,定义一个属性结构,拥有一个整型的成员变量。
- 第 11 行,定义属性值的方法。设置属性值方法的接收器类型为指针,因此可以修改成员值,即便退出方法,也有效。
- 第 17 行,定义获取值的方法。
- 第 22 行,实例化属性结构。
- 第 24 行,设置值,此时成员变量变为 100。
- 第 26 行,获取成员变量。
3.2.2 理解非指针类型的接收器
当方法作用于非指针接收器时,Go语言会在代码运行时将接收器的值复制一份,在非指针接收器的方法中可以获取接收器的成员值,但修改后无效
。
点(Point)使用结构体描述时,为点添加 Add() 方法,这个方法不能修改 Point 的成员 X、Y 变量,而是在计算后返回新的 Point 对象,Point 属于小内存对象,在函数返回值的复制过程中可以极大地提高代码运行效率,详细过程请参考下面的代码。
package main
import (
“fmt”
)
// 定义点结构
type Point struct {
X int
Y int
}
// 非指针接收器的加方法
func (p Point) Add(other Point) Point {
// 成员值与参数相加后返回新的结构
return Point{p.X + other.X, p.Y + other.Y}
}
func main() {
// 初始化点
p1 := Point{1, 1}
p2 := Point{2, 2}
// 与另外一个点相加
result := p1.Add(p2)
// 输出结果
fmt.Println(result)
}
代码输出如下:
{3 3}
代码说明如下:
- 第 8 行,定义一个点结构,拥有 X 和 Y 两个整型分量。
- 第 14 行,为 Point 结构定义一个 Add() 方法,传入和返回都是点的结构,可以方便地实现多个点连续相加的效果,例如P4 := P1.Add( P2 ).Add( P3 )
- 第 20 和 21 行,初始化两个点 p1 和 p2。
- 第 23 行,将 p1 和 p2 相加后返回结果。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-wcmNKetn-1712970082694)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!