## 结构体
一个结构体就是一个聚合的数据类型,其实每一个成员都可以看做是独立的变量. 所以可以进行指针操作.
## 结构体零值
结构体类型的零值是每个成员都是零值。通常会将零值作为最合理的默认值。
## 值类型和指针类型
### 值类型
~~~
type User struct {
Name string
Age int
}
func main() {
u1 := User{
Name: "jack",
Age: 10,
}
u2 := u1
u2.Name = "milan"
fmt.Println(u1)
fmt.Println(u2)
}
~~~
```
{jack 10}
{milan 10} //值发生了改变
```
### 指针类型
~~~
type User struct {
Name string
Age int
}
func main() {
u1 := &User{
Name: "jack",
Age: 10,
}
u2 := u1
u2.Name = "milan"
fmt.Println(u1)
fmt.Println(u2)
}
~~~
```
&{milan 10}
&{milan 10} //两个值一起改变了
```
## 结构体值类型不能包含自己
一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身。(该限制同样适应于数组。)但是S类型的结构体可以包含`*S`指针类型的成员,这可以让我们创建递归的数据结构,比如链表和树结构等。
## 字面值
结构体值也可以用结构体字面值表示,结构体字面值可以指定每个成员的值。
~~~
type Point struct{ X, Y int }
p := Point{1, 2}
~~~
这里有两种形式的结构体字面值语法,上面的是第一种写法,要求以结构体成员定义的顺序为每个结构体成员指定一个字面值。它要求写代码和读代码的人要记住结构体的每个成员的类型和顺序,不过结构体成员有细微的调整就可能导致上述代码不能编译。因此,上述的语法一般只在定义结构体的包内部使用,或者是在较小的结构体中使用,这些结构体的成员排列比较规则,比如image.Point{x, y}或color.RGBA{red, green, blue, alpha}。
其实更常用的是第二种写法,以成员名字和相应的值来初始化,可以包含部分或全部的成员,如1.4节的Lissajous程序的写法:
~~~
anim := gif.GIF{LoopCount: nframes}
~~~
## 结构体比较
如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的(slice,map,func不可比较),那样的话两个结构体将可以使用==或!=运算符进行比较。相等比较运算符==将比较两个结构体的每个成员.
## 匿名成员
匿名成员可以省略中间匿名成员的名称直接去"."来进行访问. 但是如果匿名成员首字母是小写的(非导出),那么在该包内是可以访问的,但是在包外是不能访问的.
- 基本语法
- 申明变量
- 常量
- 数据类型
- 强制类型转换
- 获取命令行参数
- 指针
- 概述
- new函数
- 函数
- 概述
- 不定参数类型
- 有返回值
- 函数类型
- 回调函数
- 匿名函数和闭包
- 延迟调用defer
- 工程管理
- 工作区
- src,pkg和bin目录
- 复合类型
- 概述
- 数组
- 概述
- 声明并初始化
- 拷贝传值
- slice
- 概述
- 创建切片
- 切片截取
- 切片和底层数组的关系
- slice常用方法
- 切片做函数参数
- map
- 概述
- map操作
- 结构体
- 概述
- 结构体初始化
- 结构体比较
- 结构体作为函数参数
- 结构体前加&
- 面向对象
- 概述
- 匿名组合
- 方法
- 值语义和引用语义
- 方法集
- 方法的继承
- 方法重写
- 方法值
- 接口
- 接口定义和实现
- 多态的表现
- 接口继承
- 接口转换
- 空接口
- 类型断言
- 异常处理
- error接口
- panic
- recover
- 文本文件处理
- 字符串操作
- 正则表达式
- json处理
- 文件操作
- 标准设备文件操作
- 并发编程
- 概述
- 并发和并行
- go语言并发优势
- goroutine
- goroutine概述
- 创建goroutine
- 主协程先退出
- runtime包
- Gosched
- Goexit
- GOMAXPROCE
- channel
- 多资源竞争
- channel类型
- 无缓冲channel
- 有缓冲channel
- 关闭channel
- 单向channel
- 单向channel特性
- 定时器
- Timer
- Ticker
- select
- select作用
- 超时
- sync
- 竞争状态
- 网络编程
- 网络概述
- 网络协议
- 分层模型
- 网络分层架构
- 层与协议
- 每层协议的功能
- 链路层
- 网络层
- 传输层
- 应用层
- socket编程
- 组合和继承
- 注意事项
- 细节
- go语言实现队列
- google工程师golang
- 基础语法
- 内建容器
- 面向"对象"
- 依赖管理
- 面向接口
- 函数式编程
- 错误处理和资源管理
- 测试与性能调优
- goroutine
- channel
- golang问题集
- 断言和类型转换
- Go语言圣经
- 入门
- 程序结构
- 命名
- 声明
- 变量
- 赋值
- 类型
- 包和文件
- 作用域
- 基础数据类型
- 整数
- 浮点数
- 复数
- 布尔型
- 字符串
- 常量
- 复合数据类型
- 数组
- slice
- map
- 结构体
- json
- 文本和HTML模板
- 函数
- 函数声明
- 错误
- 函数值
- 匿名函数
- defer
- panic
- recover
- 方法
- 方法声明
- 指针对象的方法
- 封装
- 接口
- 说明
- 接口是合约
- 实现接口的条件
- 接口值
- 类型断言
- 通过类型断言询问行为
- 类型开关
- Goroutines和Channels
- 协程
- channels
- 无缓冲channel
- 串联的channel
- 有缓冲channel
- 并发的循环
- select多路复用
- 并发的退出
- 并发问题的自我思考
- 基于共享变量的并发
- 竞争条件
- 互斥锁
- 读写锁
- 内存同步
- sync.Once
- 协程和线程
- 包和工具
- 测试
- 反射
- 什么是反射
- 为什么需要反射
- reflect.Type和reflect.Value
- 通过reflect.Value修改值
- 底层编程
