Go语言核心36讲
郝林
《Go并发编程实战》作者,前轻松筹大数据负责人
立即订阅
24139 人已学习
课程目录
已完结 54 讲
0/4登录后,你可以任选4讲全文学习。
开篇词+学习路线 (3讲)
开篇词 | 跟着学,你也能成为Go语言高手
免费
预习篇 | 写给0基础入门的Go语言学习者
50 | 学习专栏的正确姿势
模块一:Go语言基础知识 (6讲)
01 | 工作区和GOPATH
02 | 命令源码文件
03 | 库源码文件
04 | 程序实体的那些事儿(上)
05 | 程序实体的那些事儿(中)
06 | 程序实体的那些事儿 (下)
模块二:Go语言进阶技术 (16讲)
07 | 数组和切片
08 | container包中的那些容器
09 | 字典的操作和约束
10 | 通道的基本操作
11 | 通道的高级玩法
12 | 使用函数的正确姿势
13 | 结构体及其方法的使用法门
14 | 接口类型的合理运用
15 | 关于指针的有限操作
16 | go语句及其执行规则(上)
17 | go语句及其执行规则(下)
18 | if语句、for语句和switch语句
19 | 错误处理(上)
20 | 错误处理 (下)
21 | panic函数、recover函数以及defer语句 (上)
22 | panic函数、recover函数以及defer语句(下)
模块三:Go语言实战与应用 (27讲)
23 | 测试的基本规则和流程 (上)
24 | 测试的基本规则和流程(下)
25 | 更多的测试手法
26 | sync.Mutex与sync.RWMutex
27 | 条件变量sync.Cond (上)
28 | 条件变量sync.Cond (下)
29 | 原子操作(上)
30 | 原子操作(下)
31 | sync.WaitGroup和sync.Once
32 | context.Context类型
33 | 临时对象池sync.Pool
34 | 并发安全字典sync.Map (上)
35 | 并发安全字典sync.Map (下)
36 | unicode与字符编码
37 | strings包与字符串操作
38 | bytes包与字节串操作(上)
39 | bytes包与字节串操作(下)
40 | io包中的接口和工具 (上)
41 | io包中的接口和工具 (下)
42 | bufio包中的数据类型 (上)
43 | bufio包中的数据类型(下)
44 | 使用os包中的API (上)
45 | 使用os包中的API (下)
46 | 访问网络服务
47 | 基于HTTP协议的网络服务
48 | 程序性能分析基础(上)
49 | 程序性能分析基础(下)
尾声与思考题答案 (2讲)
尾声 | 愿你披荆斩棘,所向无敌
新年彩蛋 | 完整版思考题答案
Go语言核心36讲
登录|注册

13 | 结构体及其方法的使用法门

郝林 2018-09-10
我们都知道,结构体类型表示的是实实在在的数据结构。一个结构体类型可以包含若干个字段,每个字段通常都需要有确切的名字和类型。

前导内容:结构体类型基础知识

当然了,结构体类型也可以不包含任何字段,这样并不是没有意义的,因为我们还可以为类型关联上一些方法,这里你可以把方法看做是函数的特殊版本。
函数是独立的程序实体。我们可以声明有名字的函数,也可以声明没名字的函数,还可以把它们当做普通的值传来传去。我们能把具有相同签名的函数抽象成独立的函数类型,以作为一组输入、输出(或者说一类逻辑组件)的代表。
方法却不同,它需要有名字,不能被当作值来看待,最重要的是,它必须隶属于某一个类型。方法所属的类型会通过其声明中的接收者(receiver)声明体现出来。
接收者声明就是在关键字func和方法名称之间的圆括号包裹起来的内容,其中必须包含确切的名称和类型字面量。
接收者的类型其实就是当前方法所属的类型,而接收者的名称,则用于在当前方法中引用它所属的类型的当前值。
我们举个例子来看一下。
// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
kingdom string // 界。
phylum string // 门。
class string // 纲。
order string // 目。
family string // 科。
genus string // 属。
species string // 种。
}
func (ac AnimalCategory) String() string {
return fmt.Sprintf("%s%s%s%s%s%s%s",
ac.kingdom, ac.phylum, ac.class, ac.order,
ac.family, ac.genus, ac.species)
}
结构体类型AnimalCategory代表了动物的基本分类法,其中有 7 个string类型的字段,分别表示各个等级的分类。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Go语言核心36讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(42)

  • melon
    方法的定义感觉本质上也是一种语法糖形式,其本质就是一个函数,声明中的方法接收者就是函数的第一个入参,在调用时go会把施调变量作为函数的第一个入参的实参传入,比如
    func (t MyType) MyMethod(in int) (out int)
    可以看作是
    func MyMethod(t Mytype, in int) (out int)

    比如 myType.MyMethod(123) 就可以理解成是调用MyMethod(myType, 123),如果myType是*MyType指针类型,则在调用是会自动进行指针解引用,实际就是这么调用的 MyMethod(*myType, 123),这么一理解,值方法和指针方法的区别也就显而易见了。
    2018-09-10
    43
  • 大马猴
    return a.AnimalCategory.String(),这叫链式表达式吗?这不就是普通的调用吗?老乱用概念,让人很难理解
    2018-12-17
    16
  • 来碗绿豆汤
    思考题1, 我们可以在结构体中嵌入某个类型的指针类型, 它和普通指针类似,默认初始化为nil,因此在用之前需要人为初始化,否则可能引起错误
    思考题2, 空结构体不占用内存空间,但是具有结构体的一切属性,如可以拥有方法,可以写入channel。所以当我们需要使用结构体而又不需要具体属性时可以使用它。
    2018-09-11
    15
  • colben
    嘿嘿,看了郝老师的《go并发编程》,里面讲到空结构体类型变量不占内存空间,内存地址相同,建议用于在通道里传递“信号”……
    2018-09-11
    10
  • ossic
    貌似github上的代码并没有更新
    2018-09-10
    7
  • Q卓玛的男人
    感觉值方法修改的只是类型值的副本,这个很容易弄错误认为已经更新了类型值本身。那么如果我们定义方法都定义为指针方法,而不用值方法,会有什么问题吗?
    2018-09-11
    6
  • 苏浅
    每篇文章都有一个配图,这是有啥讲究吗?还是就是觉得好看?😏
    2018-09-10
    1
    6
  • 卡卡爱漂流
    如果一个method的receiver是*T,你可以在一个T类型的实例变量V上面调用这个method,而不需要&V去调用这个method;
    如果一个method的receiver是T,你可以在一个*T类型的变量P上面调用这个method,而不需要 *P去调用这个method。

    所以,不用担心你是调用的指针的method还是不是指针的method,Go知道你要做的一切
    2018-09-28
    5
  • colben
    go语言的结构体甚得我心!2009年我上大二学c++开始接触对象的概念,当时发现类的私有变量、成员函数完全可以用c的结构体配合函数指针来实现,完全没有必要去搞“类”!可惜后来的Java和python都没有摆脱class这个关键字,这次的go终于甩掉了臃肿的“对象”!
    2018-09-10
    5
  • 风中花
    老师的专业术语用的啊,我能坚持到现在我也不容易啊 ,费劲啊 。
    2019-07-17
    3
  • Yayu
    第二次学习本章节,对老师讲解的内容有了清晰的认识。回答一下老师的问题。1.一个结构体可以嵌入一个类型的指针类型,而且被嵌入的类型还可以是它自己,这样可以构造出树的数据结构。2.struct{}是一个空结构体字面量表示,它可以用来给一个变量赋值,这个变量虽然没有字段,但是可以绑定方法。
    2018-09-18
    3
  • 🐶
    1. 可以嵌入某个类型的指针类型,包括本结构体的指针类型,例如树的结构体的声明。但是在使用之前需要初始化
    2. struct{}代表是一个空结构体,不占用内存空间,但是也是一个结构体!

    作者回复: 嗯,对。

    2019-08-11
    2
  • 红科
    思考题能给出答案吗,有时候看留言也不知道哪个是正确的,自己也不会。自己谷歌查询,也是一知半解的,有时候还是不太明白。

    作者回复: 别着急,思考题答案我会在后边补发。不过可能要耗费一些时间。

    2018-10-25
    1
  • ken
    嵌入多个类型时,如果都有某个同名方法或字段,屏蔽的顺序是怎么样的?
    如果一个嵌入字段对结构体打印时会调用嵌入字段的string方法,但如果有多个嵌入字段时,都有String方法时,是如何调用的呢?
    2018-10-02
    1
  • 夏云
    这一讲概念性的文字太多,多一些例子就好了,不然第一遍云里雾里的

    作者回复: 可以对照着示例项目中的代码看,实际上我也是这么设计的。另外,这个专栏的定位也不是只讲浅显的东西。一些核心的东西需要大家仔细研习,反复琢磨。想当初我也是这么做的。我希望这些内容能给你们带来长期的好处。

    听音频可以让你们有个宏观的了解和大概的感觉,真正学起来还是需要看文字、看代码的。加油!

    2018-09-30
    1
  • 任性😀
    1、可以引入,实例化的时候需要传指针值
    2、不知道
    3、建议老师在下一遍文章里可以说说上一篇留的问题(有些看不懂啊)
    2018-09-29
    1
    1
  • Michael
    嵌入指针类型我觉得要注意的是:指针的默认值是 nil, 在对这个字段赋值之前,没法使用这个字段,调用的时候就会出错。

    而值类型初始化的时候是有默认值得,不会有这样的风险。
    2018-09-16
    1
  • jians
    测试嵌套多个结构体存在同名方法的情况,同一级别的嵌套体内不能存在相同的方法,否则在顶层调用方法时报错,看来它没办法决定使用哪一个嵌套的方法,除非通过.点定位调用。
    如果嵌套体在不同深度,会默认调用接近浅层的。
    2018-09-11
    1
  • 世风十三
    嵌入多个类型时,如果都有某个同名方法或字段,屏蔽的顺序是怎么样的?优先级?
    2018-09-10
    1
  • Iflei
    一方面说go支持面向对象,一方面说go没有继承,这不很矛盾吗?面向对象三大特性之一就是继承,没有继承也敢叫面向对象。只是继承实现的方式不同罢了

    作者回复: Go 是把多个编程范式有机地融合在一起了。继承其实是很容易引起程序复杂度飙升的一个东西。GoF 提倡的设计原则中也有“多用组合,少用继承”一条。这不正是 Go 所做的嘛?组合和继承是两个不同的东西,虽然它们在某些时候可以起到同样的作用。

    我觉得纯粹的 OO 有利有弊,而且不能说没有完全实现OO 的所有思想就不算支持 OO。

    2019-12-09
收起评论
42
返回
顶部