go 语言基础
1 基本数据类型
python: int(int, float, long, complex, 布尔值(0, 1)) bool(True, False) string list tuple dict set
go:
布尔型(true, false)
eg:var a bool = true
数字型(int, float32, float64, complex)
字符串型(utf-8编码表示的unicode文本)
派生类型(指针类型,数组类型,结构化类型,channel类型,函数类型,切片类型,接口类型, map类型)
2 变量
变量命名规则:是由数字,字母,下划线组成,注意首个字符不能是数字,和python一样
go: 一般形式使用var关键字
var b int = 1
var b string = 'hi'
var b int //没有初始值,默认为0
var b bool //默认false
var b = true //自行判断变量类型
b := 1 //会报错, 整数类型都会报错,其他都不会报错
b := 'hi' //不会报错
a, b := 1, 2 //不会报错, ':='这时是一个声明语句
3 常量 (不会被修改的量)
go格式:const identifier [type] = value
多个常量可以的写法:
const a, b = 1, 2
(python没有常量,只能自定义类来实现)
常量可以作为枚举:
const(
key1 = value
key2 = value
key3 = value
)
iota: 特殊常量,可以认为是一个可以被编译器修改的常量
iota在const可以看作是每一行的索引,也可以作为枚举值
eg:const(
a = iota
b
c
)
4 运算符
4.1 算数运算符
+, -, *, /, %, ++(自增,), --(自减)
注意:python 没有++,--
4.2 关系运算符
==, !=, >, <, >=, <=
4.3 逻辑元素符
&&(相当于and), ||(相当于or), !(相当于not)
python: and or not
4.4 位运算(对整数在内存的二进制位进行操作)
4.5 赋值元算符
=, +=, -=, +=, *=, /=, %=, <<=, >>=, &=, ^=, |=
4.6 其他运算符
&(&a:将给出变量的实际地址), *(*a:是一个指针变量)
5 条件语句
if语句
if...else...语句
上面两个python都有,但是go有大括号,不用像python一样内容空四格
switch语句:
语法:
switch var1{
case val1:
.....
case val2:
.....
case val3, val4:
.....
default:
....
}
注意: 如果case中带有fallthrough,程序会继续执行下一条case
select语句:
语法:
select{
case communication clause:
......
case communication clause:
......
default:
......
}
select随机执行一个case.如果没有case可运行,它将阻塞,直到case可运行,如果有default则执行
6 语言循环语句
6.1 for循环
for init;condition;post{}
for condition;
for{}
init: 一般为赋值表达式,给控制变量赋予初值
condition: 关系表达式或逻辑表达式,循环控制条件
post: 一般为赋值表达式,给控制变量增量或减量
6.2 循环语句控制语句
break, continue, goto(将控制转移到被标记的语句)
7 语言函数
7.1 只能有一个,并且必须出现main()函数
7.2 函数申明告诉编译器函数的名称,返回的类型,和参数
7.3 内置函数,eg: len()
语法:
func function_name(parameter list) (return_type) {}
8 变量作用域(局部变量,全局变量,形式参数)
局部变量:函数内定义的变量
全局变量:函数外定义的变量
形式参数:函数定义中的变量(作为函数局部变量来使用)
9 数组
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形,字符串或自定义类型。
可以通过索引来读取或者修改
语法:
var variable_name [SIZE] variable_type
eg:
var balance[10] float32
多维数组:
语法:
var variable_name [size1][size2]...[sizen] variable_type
eg:
var threedim [5][10][4] int
想函数传递数组:
如果你想向函数传递数组参数,你需要在函数定义时,声明形参为数组:
语法1:
void myFunction(param [10]int) {}
语法2:
void myFunction(param []int) {}
10 指针
指针变量指向了一个值的内存地址
语法:
var var_name *var-type
eg:
var ip *int
var fp *float32
变量是一种使用方便的占位符,用于引用计算机内存地址
go语言的取地址符&,放到一个变量前面就会返回相应变量的内存地址
python 获取变量的内存地址是使用id()
使用指针:
在指针类型前面加上*号来获取指针所指向的内容
空指针:
当一个指针被定义后没有分配到任何变量时,它的值为nil
nil指针称为空指针,和其他语言的null, None, nil, NULL一样。
一个指针变量通常缩写为ptr
指向指针的指针:
如果一个指针变量存放的又是另外一个指针变量的地址,则称这个指针变量为指向指针的指针变量
语法:
var ptr **int
11 结构体
结构体:由一系列具有相同类型或不同类型的数据构成的数据集合
语法:
type struct_variable_type struct {
member definition;
member definition;
...
member definition;
}
一旦定义了结构体类型,它就能用于变量的声明,格式:
variable_name := structure_variable_type{val1, val2, valn}
variable_name := structure_variable_type{key1:val1, key2:val2, key3:val3...,keyn:valn}
有点类似于python的字典
12 切片(slice)
切片是对数组的抽象
go数组的长度不可改变,go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度不固定,可以追加元素在切片中
语法:
var identifier []type
切片不需要说明长度,可以使用make()函数创建切片
var slice1 []type = make([]type,len)
slice1 := make([]type,len)
eq:
s := []int{1, 2, 3}
len()和cap()函数:
切片是可索引的,并且可以由len()方法获取长度
切片提供了计算容量的方法cap()可以测试切片最长可以达到多少
append()和copy()函数:
如果增加切片的容量,我必须创建一个新的更大的切片并把原分片内容拷贝过来
13 范围(Range)
go语言中range关键字用于for循环中,迭代数组(array),切片(slice), 通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回key-value对的key值
14 Map(集合)
是一种无序的键值对的集合。Map最重要的一点是通过Key来检索值
Map是一种集合,所以可以像迭代数组和切片那样迭代它。map是无序的
语法:
var map_variable map[key_data_type]value_data_type
map_variable := make(map[key_data_type]value_data_type)
如果不初始化map,那么就会创建一个nil map。nil map不能用来存放键值对
delete()函数:
用于删除集合的元素,参数为map和其对应的key
语法:
delete(map_name, key_name)
15 递归函数
递归,就是运行的过程中调用自己,注意设置出口,不然将会死循环中
语法:
func recursion() {
recursion()
}
func main() {
recursion()
}
16 类型转换
类型转换,将一种数据类型的变量转换为另外一种类型的变量
type_name(expression)
17 接口
提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法,就是实现了这个接口
eg:
type interface_name interface {
method_name1[return_type]
method_name2[return_type]
method_name3[return_type]
....
}
type struct_name struct {
/*variables*/
}
func (struct_name_variable struct_name) method_name1() [return_type] {}
func (struct_name_variable struct_name) method_name1() [return_type] {}
18 错误处理
go语言通过内置的错误接口提供了非常简单的错误处理机制
语法:
type error interface {
Error() string
}
函数通常在最后的返回值中返回错误信息。使用errors.New可以返回错误信息
还以可以使用recover函数来捕捉异常
defer func() {
fmt.Println(recovner())
}
19 并发
只需要通过go关键字来开启goroutine即可
goroutine是轻量级线程,goroutine的调度是由golang运行管理的
语法:
go 函数名(参数列表)
eg: go f(x,y,z)
开启一个新的goroutine:f(x, y, x)
20 通道(channel)
通道(channel)是用来传递数据的一个数据结构
通道可用于两个goroutine之间通过传递一个指定类型的值来同步运行和通讯。操作符<-用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道
语法:
ch <- v //把发送到通道ch
v := <-ch //从ch接收数据,并赋值给v
用关键字chan声明:
ch := make(chan int)
通道缓冲区:
通道可以设置缓冲区,通过make的第二个参数指定缓冲区大小
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。
不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了
关闭通道close(通道名)