1 变量
1.1 变量 – 声明
变量声明标准格式:var
变量名 变量类型
示例:var a int
var
语句可以定义在包或函数内。
a. 后置变量类型
b. 变量命名规则遵循驼峰命名法
c. 声明变量后,系统会自动赋予该类型零值
d. 声明但是未使用的变量会被视为错误
1.1.1 零值
- 变量在定义时没有明确的初始化时会赋值为零值。
- 数值类型为 0
- 布尔类型为 false
- 字符串为 “”
1.2 变量 – 初始化
变量定义可以包含初始值,每个变量对应一个。
变量从初始值中获得类型。
// 标准格式
var 变量名 变量类型 = 表达式
// 示例
var a string = “hello”
// 推导格式
var 变量名 = 表达式
// 示例
var a = “hello”
短声明变量
- 在函数中,
:=
简洁赋值语句在明确类型的地方,可以用于替代var
定义。 - 函数外的每个语句都必须以关键字开始(
var
、func
、等等),:=
结构不能使用在函数外。
// 短格式
变量名 := 表达式
// 示例
a := “hello”
1.3 变量 – 作用域
- 全局变量作用域为整个包
- 局部变量的作用域由花括号决定,任一变量的作用域仅在所处花括号内
1.4 变量 – 变量覆盖
package main
import "fmt"
func main() {
a := 1
fmt.Println(a)
{
a := 2
fmt.Println(a)
}
fmt.Println(a)
}
编译结果:
1
2
1
package main
import "fmt"
func main() {
a := 1
fmt.Println(a)
{
a = 2
fmt.Println(a)
}
fmt.Println(a)
}
编译结果:
1
2
2
package main
import "fmt"
func main() {
a := 1
a := 2
fmt.Println(a)
}
编译报错
2 类型系统
2.1 类型系统 – 基本类型

2.2 类型系统 – 基本类型转换
数值类型(byte
,rune
, intX
, uintX
, floatX
)之间的转换需要通过类型强转来完成
var a int32 = 123
var b int64 = int64(a)
数值类型和string
之间的转换通过 标准库strconv
中提供的函数进行
// string 到 int
int, err := strconv.Atoi(string)
// string 到 int64
int64, err := strconv.ParseInt(string, 10, 64)
// int 到 string
string := strconv.Itoa(int)
// int64 到 string
string := strconv.FormatInt(int64, 10)
2.3 类型系统 – 引用类型
- 特指 slice 、 map 、channel 三种类型
- 引用类型具有更复杂的存储结构
2.4 类型系统 – 自定义类型
使用关键字 type
定义用户自定义类型
package main
func main() {
// 基于基本类型创建自定义类型
type MyInt int
// 自定义结构体类型
type MyStruct struct {
a int
}
// 自定义函数类型
type MyFunc func(int) int
}
3 指针
指针、变量和地址: 每个变量都有地址,指针的值就是地址
package main
import "fmt"
func main() {
var cat int = 1
var str string = "banana"
var catPtr *int = &cat
var strPtr *string = &str
fmt.Printf("%p %p\n", catPtr, strPtr)
}
编译结果:
0xc00000a0a8 0xc000040230
3.1 指针 – 通过指针修改变量的值
package main
import "fmt"
func main() {
// 准备两个变量,赋值1和2
x, y := 1, 2
// 交换变量值
swap(&x, &y)
// 输出变量值
fmt.Println(x, y)
}
// 交换函数
func swap(a, b *int) {
// 取a指针的值,赋给临时变量t
t := *a
// 取b指针的值,赋给a指针指向的变量
*a = *b
// 将a指针的值赋给b指针指向的变量
*b = t
}
编译结果:
2 1
4 关键字
- var和const:变量和常量的声明
- package && import:引包
- func:用于定义函数和方法
- return:用于从函数返回
- defer:在函数退出前执行
- go:用于并行
- select 用于选择不同类型的通讯
- interface 用于定义接口
- struct 用于定义抽象数据类型
- break、case、continue、for、fallthrough、else、if、switch、goto、default:流程控制
- chan:用于channel通讯
- type:用于声明自定义类型
- map:用于声明map类型数据
- range:用于读取slice、map、channel数据
5 运算符
5.1 算术运算符

5.2 赋值运算符

5.3 关系运算符

5.4 逻辑运算符

5.5 运算符 – 优先级

优先级
值越大表示优先级越高
结合性
指相同优先级在同一表达式中,且没有括号的时候,操作数计算的顺序
6 流程控制
6.1 流程控制 – 分支结构
// 1. 简单形式
if condition {
// todo
}
// 2. 简单形式
if condition1 {
// todo
} else if condition2 {
// todo
} else {
// default
}
// 3. 特殊写法,可以在if表达式之前添加一个执行语句,再根据变量值进行判断
if err := Connect(); err != nil {
fmt.Println(err)
return
}
6.2 流程控制 – 循环结构
// 完整形式
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
// 初始语句、条件表达式、结束语句可以有一个或多个为空
sum := 0
i := 0
for ; i < 10; i++ {
sum += i
}
// 无线循环
for {
sum++
if sum > 100 {
break
}
}
不支持
while
循环支持break
和continue
6.3 流程控制 – switch
package main
import "fmt"
func main() {
var a = "hello"
switch a {
case "hello":
fmt.Println(1)
case "world":
fmt.Println(2)
default:
fmt.Println(0)
}
}
编译结果:
1
package main
import "fmt"
func main() {
var s = "hello"
switch {
case s == "hello":
fmt.Println(1)
fallthrough
case s == "world":
fmt.Println(2)
default:
fmt.Println(0)
}
}
编译结果:
1
2
7 代码风格
- 每行结束后不需要分号 ‘
;
’ - 大括号不能换行放置
if condition
{
// todo
}
- 自加、自减不再是一个操作符,而是一条语句
- 变量或者 import 的包没有使用到,则编译报错
- 可以安装gofmt工具,设置ide保存时自动格式化
网友评论