一、标识符与关键字
go变量、常量、自定义类型、包、函数的命名方式必须遵循以下规则:
- 首字符可以是任意Unicode字符或下划线;
- 首字符之外的部分可以是Unicode字符、下划线或数字;
- 名字的长度无限制;
理论上名字里可以有汉字,甚至可以全是汉字,但实际中不要这么做
1.1 关键字
https://golang.google.cn/ref/spec
break,default,func,interface,select,case,defer,go,map,struct,chan,else,goto,package,switch,const,if,range,type,continue,for,import,return,fallthrough,var
1.2 常量
true,false,iota,nil
1.3 数据类型
int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,uintptr,float32,float64,complex128,complex64,bool,byte,rune,string,error
1.4 函数
make,len,cap,new,append,copy,close,delete,complex,real,imag,panic,recover
二、运算符与表达式
2.1 算数运算符
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除取商 |
% | 求余 |
2.2 关系运算符
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,如果相等返回True否则返回False |
!= | 检查两个值是否不相等,如果不相等返回True否则返回False |
> | 检查左边值是否大于右边值,如果是返回True否则返回False |
>= | 检查左边值是否大于或等于右边值,如果是返回True否则返回False |
< | 检查左边值是否小于右边值,如果是返回True否则返回False |
<= | 检查左边值是否小于或等于右边值,如果是返回True否则返回False |
2.3 逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑AND运算符;如果两边的操作数都是True,则为True,否则为False |
|| | 逻辑OR运算符;如果两边的操作数有一个是True,则为True,否则为False |
! | 逻辑NOT运算符;如果条件为False,则为True,否则为True |
2.4 位运算符
运算符 | 描述 |
---|---|
& | 参与运算的两数各对应的二进位相与(两位均为1才为1) |
| | 参与运算的两数各对应的二进位相或(两位有一个为1就为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相同时为0,不同是为1。作为一元运算符时表示按位取反,符号位也跟着变 |
<< | 左移n位就是乘以2的n次方。a<<b是把a的各二进位全部左移b位,高位丢弃,低位补0。通过左移,符号位可能会变 |
>> | 右移n位就是除以2的n次方。a>>b是把a的各二进位全部右移b位,正数高位补0,负数高位补1 |
2.5 赋值运算符
运算符 | 描述 |
---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
+= | 相加后再赋值 |
-+ | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
<<= | 左移后再赋值 |
>>= | 右移后再赋值 |
&= | 按位与后赋值 |
!= | 按位或后赋值 |
^= | 按位异或后赋值 |
2.6 优先级
分类 | 描述 | 关联性 |
---|---|---|
Postfix后缀 | () [] -> . ++ - - | Left to right |
Unary单目 | + - ! ~ ++ - - (type)* & sizeof | Right to left |
Multiplicative乘除 | * / % | Left to right |
Additive加减 | + - | Left to right |
Shift移位 | << >> | Left to right |
Relational关系 | < <= > >= | Left to right |
Equality相等 | == != | Left to right |
Bitwise AND | & | Left to right |
Bitwise XOR | ^ | Left to right |
Bitwise OR | | | Left to right |
Logical AND | && | Left to right |
Logical OR | || | Left to right |
Assignment赋值 | = += -= *= /= %=>>= <<= &= ^= |= | Right to left |
Comma逗号运算符 | , | Left to right |
优先级由高到低
单目运算符 > 算术运算符 > 位移运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符
其中,将 “位运算符” 大分支 分为了 位移运算符 <<、>> 和 位运算符 |、^、&。
三、变量、常量、字面量
3.1 变量类型
类型 | go变量类型 | 缺省格式符 | 常用格式符 |
---|---|---|---|
整型 | int,int8,int16,int32,int64 | %d | %d,%b,%x |
无符号整型 | uint,uint8,uint16,uint32,uint64 | %d,如果使用%#v就等周%#x | %d,%b,%x |
浮点型 | float32,float64 | %g | %f,%e |
复数 | complex128,complex64 | %g | |
布尔型 | bool | %t | %t |
指针 | uintptr | %p | |
引用 | map slice channel | %v | |
字节 | byte | %c | %c,%d |
任意字符 | rune | %c | %c,%d |
字符串 | string | %s | %s |
索引0元素地址 | slice | %p | |
错误 | error | %v |
3.1.1 变量声明
1 | //标准声明 |
3.1.2 变量初始化
如果声明后未显式初始化,数值型初始化0,字符串初始化为空字符串,布尔型初始化为false,引用类型、函数、指针、接口初始化为nil
1
2
3
4
5//比如以下几种变量初始化方式
var a string="china"
var a,b int=3,7
var a="china" //类型推断,通过赋值数据类型反推变量类型
var a,b="china",7函数内部的变量(非全局变量)可以通过
:=
声明并初始化1
a:=3
下划线表示匿名变量
1
_=2+4
匿名变量不占命名空间,不会分配内存,因此可以重复使用
3.2 常量
常量在定义时必须赋值,且程序运行期间其值不能改变
1 | //常量的几种常见赋值方式 |
常量中的iota
,iota
是go语言的常量计数器,只能在常量的表达式中使用
使用iota
时只需要记住以下两点
1.iota
在const
关键字出现时将被重置为0。
2.const
中每新增一行常量声明将使iota
计数一次(iota可理解为const
语句块中的行索引)。
1 | //常量的几种iota常见赋值方式 |
3.3 字面量
字面量:没有出现变量名,直接出现了值。基础类型的字面量相当于是常量
3.3.1 整型字面量
整型字面量使用特定的字符序列表示具体的整型数值。常用于整型变量或常量的初始化。例如:
1 | fmt.Printf("%d\n", 4) |
3.3.2 浮点型字面量
浮点型字面量使用特定字符序列来表示一个浮点数值。它支持两种格式:一种是标准的数学小数形式,例如0.23;另一种是科学计数法,例如1E6。
1 | fmt.Printf("%d\n", 0.23) |
3.3.3 复数类型字面量
复数类型字面量使用特定的字符序列来表示复数类型的常量值。
1 | fmt.Printf("%v\n", .4i) //0.4i |
3.3.4 字符型字面量
Go的源码采用UTF-8的编码方式,UTF-8字符占用1~4个字节。Go的字符采用一对单引号包裹。
1 | fmt.Printf("%d %d\n", '\u4f17', '众') |
3.3.5 字符串字面量
Go中的字符串字面量表现形式是采用一对双引号或一对”`”包裹的字符字面量或其编码值。
1 | fmt.Printf("Hello\nWorld\n!\n") |
四、变量作用域
Go 语言 中的一个 变量(常量、类型或 函数)在程序中都有一定的作用范围,我们称之为作用域。Go 语言变量作用域分为局部作用域和全局作用域
4.1 局部变量
在函数内部声明/定义的变量叫局部变量,局部变量的作用域仅限于函数内部。在函数内部定义的变量,函数的 参数 和 返回值,if 和 for 结构内部使用的变量等都是局部变量。
下面的 main() 函数中使用到了局部变量 a、b、c
1 | package main |
运行结果如下所示:
1 | a = 3, b = 4, c = 7 |
4.2 全局变量
在函数外部声明/定义的变量叫全局变量。如果首字母为大写,则作用域在整个程序有效,如果为小写,作用域在整个包中有效。
下面代码中,第 3 行定义了全局变量 c
1 | package main |
运行结果如下所示:
1 | a = 3, b = 4, c = 7 |
全局变量与局部变量名称可以相同,但是函数体内的局部变量会被优先考虑
1 | package main |
运行结果如下所示:
1 | a = 3 |
五、注释与godoc
5.1 注释的形式
- 单行注释,以//开头
- 多行注释,连续多行以//开头 或者在段前使用/* 段尾使用*/
- 多行注释之间不能出现空行
- NOTE:引人注意,TODO:将来需要优化,Deprecated:变量或函数强烈建议不要使用
- 注释行前加缩进即可写go代码
- 包注释,在package xxx的上方。一个包只需要在一个地方写包注释,通常会专门写一个doc.go,里面只有一行package xxx和关于包的注释
- 结构休注释,在type xxx struct上方
- 函数注释,在func xxx()
- 行注释,在行上方或右侧
5.2 go doc
go doc是go自带命令,可以打印附于Go语言程序实体上的文档
go doc package
例如:获取某个函数在某个包中的文档注释
1 | go doc fmt Printf //会显示有关 fmt.Printf() 的使用说明。 |
5.3 godoc
godoc可以为项目代码导出网页版的注释文档
- 需要先安装:go install golang.org/x/tools/cmd/godoc@latest
- 本机启动http端口:godoc -http=:6060
- 用浏览器访问:http://127.0.0.1:6060 查看go标准库的文档