Golang的知识碎片
在此之前golang单纯看蓝山的文档,感觉学的很浅很零碎,所以打算重新看一遍。因为go by example、tour go和蓝山工作室的文档比较完善,所以下方将着重提及一些之前不太清楚的零碎知识,提醒自己。
0.Go 语言的零值机制
在 Go 语言中,所有变量在声明时都会被自动初始化为其类型的零值(zero value):
- 数值类型:
0 - 布尔类型:
false - 字符串类型:
""(空字符串) - 指针、接口、切片、映射、通道:
nil - 结构体:每个字段都初始化为其类型的零值
1.变量声明
关于变量的声明包括两部分,类型和初始值,变量会从初始值中推断出类型或从类型中推断出初始值(即零值)
2.返回值
Go 的返回值可以被命名(向前面的参数一样),return后面没有参数,就会返回没有命名的返回值
3.条件语句前简短语句
for和if 语句可以在条件表达式前执行一个简短语句
4.无条件的switch(类似于if-else)
switch {case x < 0: fmt.Println("Negative")case x == 0: fmt.Println("Zero")default: fmt.Println("Positive")}5.defer推迟/defer栈
defer语句会将函数调用推迟到外层函数返回之后执行- 被推迟的函数调用会被压入一个栈中,当外层函数返回时,被推迟的函数会按照后进先出(LIFO)的顺序执行
6.函数闭包
闭包 = 函数 + 外部变量变量
- 状态保持:闭包可以记住并修改外部变量
- 独立实例:每次调用外部函数都会创建新的闭包实例
- 实用性强:用于需要保持状态的场景
如何判断外部变量
- “这个变量是在内层函数内部定义的,还是外部定义的?”
- 再问:“内层函数是否使用了这个外部变量?”
- 如果两个答案都是”是”:那么这个变量就是被捕获的外部变量
7.方法
方法可以看作有接收者的函数,不过带指针/值参数的函数必须接受一个指针/值,不然会报错,而以指针/值为接收者的方法被调用时,接收者既能为值又能为指针,不过能不能生效另说
8.接收者类型
接收者有两种类型,值接收者和指针接收者。
使用指针接收者的两个原因:
1.方法需要修改接收者的值,值接收者只能改变副本,指针可以改变原始值
2.提高效率,每次方法调用时,Go 需要将整个结构体的数据复制一份给方法使用。如果结构体非常大,这个复制操作的开销会很大。而Go 只需要复制一个指针(通常是一个机器字长的大小,如 8 字节),开销极小。
所以,大部分的时候使用指针
tips
对于一个特定的类型,你应该决定是使用值接收者还是指针接收者,并为该类型的所有方法保持一致。
9.值类型/引用类型
这是 Go 语言中一个非常重要的概念,决定了变量如何被分配内存、如何被赋值以及如何被传递给函数。
值类型 (Value Types)
- 包括: 所有基本数据类型(如
int,float64,bool,string)、数组(Array)、结构体(struct)。 - 行为特点:
- 变量直接存储值本身。
- 赋值操作和函数传参时,会创建值的完整副本。 修改副本不会影响原始值。
- 在内存中,通常被分配在栈(Stack) 上(但编译器也可能决定分配在堆上)。
// 值类型示例:数组arr1 := [3]int{1, 2, 3}arr2 := arr1 // 将 arr1 的【所有值】完整地复制一份给 arr2
arr2[0] = 100 // 修改副本
fmt.Println(arr1) // 输出: [1 2 3] (原值未改变)fmt.Println(arr2) // 输出: [100 2 3]引用类型 (Reference Types)
- 包括: 切片(Slice)、映射(Map)、通道(Channel)、指针(Pointer)、函数(Function)。
- 行为特点:
- 变量存储的是一个“引用”(可以理解为内存地址),这个引用指向底层真正存储数据的内存空间。
- 赋值操作和函数传参时,复制的是这个“引用”(内存地址),而不是底层数据本身。 多个变量可以共享同一份底层数据。通过任何一个变量修改底层数据,其他所有引用它的变量都会“看到”这个变化。
- 底层数据通常存储在堆(Heap) 上。
// 引用类型示例:切片slice1 := []int{1, 2, 3}slice2 := slice1 // 复制的是引用(地址),现在 slice1 和 slice2 指向同一个底层数组
slice2[0] = 100 // 通过 slice2 修改底层数组
fmt.Println(slice1) // 输出: [100 2 3] (原值被改变了!)fmt.Println(slice2) // 输出: [100 2 3]总结对比表
| 特性 | 值类型 | 引用类型 |
|---|---|---|
| 代表类型 | int, array, struct, string | slice, map, channel, pointer |
| 变量存储内容 | 实际的数据值 | 指向底层数据的地址(引用) |
| 赋值/传参行为 | 复制整个数据值,创建独立副本 | 复制引用地址,共享底层数据 |
| 修改副本的影响 | 不影响原始数据 | 影响原始数据 |
| 内存主要位置 | 栈 | 堆(数据本身),变量本身可能在栈 |
10.匿名函数/结构体…
暂时不太懂,标记一下