长期记录更新go语言学习内容
安装
相关的网站:
学习过程参考了《go语言编程》图书的豆瓣链接
语言特性(挑其中有意思的记录):
函数多返回值。在静态语言中首先给出了多值返回功能 defer,panic,recover用于标准错误处理 匿名函数和闭包 非侵入式接口 goroutine进行并发编程,用channel实现了csp模型
第一章
1.不得包含源代码中没有用到的包 2.匿名变量,可以通过_,_,nickName :=GetName()的形式,只获取函数多个返回值中的一个 3.go语言常量是无类型的,它只要在相应类型的值域范围,就可以作为该类型的常量.
第二章
1.bool变量如果不赋值,默认为false 2.const()中的赋值,如果某一行之后不写,默认和前面赋一样的值 3.Go语言要求public的变量必须以 大写字母开头,private变量则以小写字母开头
4.go直接用:=赋值时会有一个默认的类型,而直接指定类型的值即便看起来与该值一样,还是无法相互赋值。例
5.与c语言去别的是取反是^
6.浮点数比较推荐引入math包,自定义精度比较,书有点老了,现在用的函数应该是Dim()
7.字符串初始化后不可变,使用下标取用直接赋值给变量,是uint8,是对应的ascii码,不会直接以字符形式显示。与python不同,go不可以使用负值下标取用倒数的某个字符。但是可以使用m:n取某个范围的字符串。go也有内置的len()
8.go语言可以以字符数组或者unicode的方式遍历字符串
9.在Go语言中数组是一个值类型(value type)。所有的值类型变量在赋值和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该参数将发生数据复制。因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是所传入数组的一个副本。如果想修改传入数组,则使用数组切片。
10.make()可用于创建数组切片,数组切片可以有比元素个数多的存储空间
11.map使用make创建,可以在创建时指定存储能力。map查找形如value, ok := myMap[“1234”]
12.函数的return不能被包含在if …else…里。
13.switch case可以没有条件表达式,此时和if …else…等价
14.go可以使用goto
15.小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其他包使用。
16.interface{}传递任意类型数据
17.闭包只要还被引用,那么被闭包引用的变量会一直存在。
1
2
3
import(
""
)
18.defer用于解决句柄关闭的问题
19.panic()和recover()没仔细看
第三章
1.go可以给任意类型添加方法
2.go的类型和c语言类似,基于值传递,其中数组切片,map,channel和接口使用类似于引用类型
1
2
3
4
5
var a = [3]int{1, 2, 3}
var b = &a
b[1]++
fmt.Println(a, *b)
// 输出结果此时相同 [1 3 3] [1 3 3],如果只是var b = a,则b[1 3 3 ] a[1 2 3 ]
3-2.初始化
定义一个类型后,初始化的方法可以有以下几种
1
2
3
4
5
6
7
8
9
type Rect struct{
x,y flaot64
width,height float64
}
rect1 :=new(Rect)
rect2 = &Rect{}
rect3 = &Rect{1,2,3,4}
rect4 = &Rect{width:100,height:2000}
3-3.匿名组合:
提供一个参考书上匿名组合的例子
1
2
3
4
type Job struct {
Command string
*log.Logger
}
在合适的赋值后,我们在Job类型的所有成员方法中可以很舒适地借用所有log.Logger提 供的方法
1
2
3
4
5
func (job *Job)Start() {
job.Log("starting now...")
... // 做一些事情
job.Log("started.")
}
需要注意的是,不管是非匿名的类型组合还是匿名组合,被组合的类型所包含的方法虽然都 升级成了外部这个组合类型的方法,但其实它们被组合方法调用时接收者并没有改变。比如上面 这个Job例子,即使组合后调用的方式变成了job.Log(…),但Log函数的接收者仍然是 log.Logger指针,因此在Log中不可能访问到job的其他成员方法和变量。
注意匿名组合可能发生名称冲突
3-4.可见性
通过大小写控制,包一级
3-5.接口
3.5.2 非侵入接口
在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口 ,并且不需要完全对应匹配。
3.5.3接口赋值
例子如下,具体涉及到golang的自动生成机制,在88页。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
func (a *Integer) Add(b Integer) {
*a += b
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
type LessAdder interface {
Less(b Integer) bool
Add(b Integer)
}
>>>>>>>>>>>>>>>>>>>>>>>>>
var a Integer = 1
var b LessAdder = &a
接口赋值并不要求两个接口必须等价。如果接口A的方法列表是接口B的方法列表的子集, 那么接口B可以赋值给接口A。
3.5.4 接口查询
1
2
3
4
var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
...
}
这个if语句检查file1接口指向的对象实例是否实现了two.IStream接口,如果实现了,则执 行特定的代码。
3.5.5类型查询
1
2
3
4
5
6
var v1 interface{} = ...
switch v := v1.(type) {
case int: // 现在v的类型是int
case string: // 现在v的类型是string
...
}
Go语言标准库的Println()是这个方法的一个很好的例子
3.5.6接口组合
可以认为接口组合是类型匿名组合的一个特定场景,只不过接口只包含方法,而不包含任何 成员变量。
3.5.7 any类型
由于Go语言中任何对象实例都满足空接口interface{},所以interface{}看起来像是可 以指向任何对象的Any类型
6.气死我了,94页代码有错,搞得我一直纠结自己,我****