go语言基础速查手册

  最近在学习go语言,总结了一些便于理解的知识点和案例,方便自查。每天积攒一点,希望有朝一日能够成为一个比较丰富的知识手册,让自己开心开心。(文章中的每一个案例是基于go1.15.5编写的,均可独立运行)

基础语法

Helloworld

1
2
3
4
5
6
7
8
package main // 声明 main 包,表明当前是一个可执行程序

import "fmt" // 导入内置 fmt 包

func main() { // main函数,是程序执行的入口
fmt.Println("Hello World!") // 在终端打印 Hello World!
}

运行结果:

1
Hello World!

常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main // 声明 main 包,表明当前是一个可执行程序

import (
"fmt" // 导入内置 fmt 包
"math" // 导入用于数学计算的包
)

func consts() {
const filename = "abc.txt"
const a, b = 3, 4
var c int
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(filename, c)
} // 常量的编写规范同理于变量,可以放在var()里,可以放在函数外

func main() {
consts()
}
1
abc.txt 5

变量

Go语言变量特点

  • 变量类型写在变量名后面
  • 编译器可推测变量类型
  • 没有char,只有rune
  • 原生支持复数类型

内建变量类型

  • bool,string
  • (u)int,(u)int8,(u)int16,(u)int32,(u)int64,uintptr
  • byte(长度8位),rune(长度32位,4字节的int32)
  • float32,float64,complex64,complex128
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main // 声明 main 包,表明当前是一个可执行程序

import "fmt" // 导入内置 fmt 包

// 定义变量
func variableZeroValue() {
var a int
var s string
fmt.Printf("%d %q\n", a, s) // 为了打印出空字符串,%q(%#q)会打印原始 (即反引号围绕的)字符串
}

// 赋值给变量
func variableInitialValue() {
var a, b int = 3, 4
var s string = "abc"
fmt.Println(a, b, s)
}
func variableTypeDeduction() {
var a, b, c, s = 3, 4, true, "def" // 赋值放在一起定义也可以
fmt.Println(a, b, c, s)
}
func variableShorter() {
a, b, c, s := 3, 4, true, "def" //不用var的形式
b = 5
fmt.Println(a, b, c, s)
}

// 函数外面定义变量,非全局变量,而是包内部变量
var aa = 3
var ss = "kkk"
var bb = true //cc := false //这样不行,函数外面必须有var或者func等关键字
var (
aaa = 33
sss = "jjj"
bbb = false
) // 用var()可以省去每行都写var关键字

func main() { // main函数,是程序执行的入口
variableInitialValue() // 主函数调用上述函数
variableZeroValue()
variableTypeDeduction()
variableShorter()
fmt.Println(aa, ss, bb)
fmt.Println(aaa, sss, bbb)
}

运行结果:

1
2
3
4
5
6
3 4 abc
0 ""
3 4 true def
3 5 true def
3 kkk true
33 jjj false

强制类型转换

go语言必须显式转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main // 声明 main 包,表明当前是一个可执行程序

import (
"fmt" // 导入内置 fmt 包
"math" // 导入用于数学计算的包
)

func triangle() {
var a, b int = 3, 4
var c int
c = int(math.Sqrt(float64(a*a + b*b))) //根据Sqrt指引得知Sqrt func(x float64) float64,参数是float64,算出来还是float64,但是c是int,所以需要显式转换
// c = math.Sqrt(a*a + b*b),这样不行
// c = math.Sqrt(float64(a*a + b*b))),这样也不行
fmt.Println(c)
}
func main() {
triangle()
}

运行结果:

1
5

普通枚举和自增枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main // 声明 main 包,表明当前是一个可执行程序

import (
"fmt" // 导入内置 fmt 包
)

//普通枚举类型和自增枚举类型
func enums() {
//普通枚举类型
const (
php = 100
)
//自增枚举类型
const (
cpp = iota //0
python //1
golang //2
javascript //3
)
//常见自增枚举类型案例
const (
b = 1 << (10 * iota)
kb
mb
gb
tb
pb
)
fmt.Println(php)
fmt.Println(cpp, javascript, python, golang)
fmt.Println(b, kb, mb, gb, tb, pb)
}
func main() {
enums()
}

运行结果:

1
2
3
100
0 3 1 2
1 1024 1048576 1073741824 1099511627776 1125899906842624

条件语句

if else语句

现在程序同目录,创建abc.txt文件,并且输入内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
"fmt"
"io/ioutil"
)

func main() {
// 第一种写法
const filename = "abc.txt"
contents, err := ioutil.ReadFile(filename) //ioutil.ReadFile是读文件的库函数
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
// 第二种写法
const filename2 = "abc.txt"
if contents, err := ioutil.ReadFile(filename2); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
//fmt.Println(contents),在if条件语句外面,无法访问contents
}

运行结果:

1
2
3
4
5
6
7
8
abcde
12345
hello
world
abcde
12345
hello
world

switch语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package main

import "fmt"

func grade(score int) string {
g := ""
switch {
case score < 0 || score > 100:
panic(fmt.Sprintf("Wrong score: %d", score))
case score < 60:
g = "F"
case score < 80:
g = "C"
case score < 90:
g = "B"
case score <= 100:
g = "A"
}
return g
}

func main() {
//调用函数的方式实现switch
a := grade(10)
fmt.Println(a)

/* 定义局部变量 */
var grade string = "B"
var marks int = 90

switch marks {
case 90:
grade = "A"
case 80:
grade = "B"
case 50, 60, 70:
grade = "C"
default:
grade = "D"
}

switch {
case grade == "A":
fmt.Printf("优秀!\n")
case grade == "B", grade == "C":
fmt.Printf("良好\n")
case grade == "D":
fmt.Printf("及格\n")
case grade == "F":
fmt.Printf("不及格\n")
default:
fmt.Printf("差\n")
}
fmt.Printf("你的等级是 %s\n", grade)

}

运行结果:

1
2
3
F
优秀!
你的等级是 A

Type Switch

使用switch语句判断interface变量中实际存储的变量类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
var a interface{}

switch i := a.(type) {
case nil:
fmt.Printf(" a 的类型 :%T", i)
case int:
fmt.Printf("a 是 int 型")
case float64:
fmt.Printf("a 是 float64 型")
case func(int) float64:
fmt.Printf("a 是 func(int) 型")
case bool, string:
fmt.Printf("a 是 bool 或 string 型")
default:
fmt.Printf("未知型")
}
}

运行结果:

1
a 的类型 :<nil>

fallthrough

使用fallthrough会强制执行后面的case语句,fallthrough不会判断下一条case的表达式结果是否为 true。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {

switch {
case false:
fmt.Println("1、case 条件语句为 false")
fallthrough
case true:
fmt.Println("2、case 条件语句为 true")
fallthrough
case false:
fmt.Println("3、case 条件语句为 false")
fallthrough
case true:
fmt.Println("4、case 条件语句为 true")
case false:
fmt.Println("5、case 条件语句为 false")
fallthrough
default:
fmt.Println("6、默认 case")
}
}

运行结果:

1
2
3
2、case 条件语句为 true
3、case 条件语句为 false
4、case 条件语句为 true

循环语句for

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
sum := 0
for i := 1; i <= 5; i++ {
sum += i
fmt.Println(sum)
}
}

运行结果:

1
2
3
4
5
1
3
6
10
15

无限循环

go语言中没有while,可以使用for来实现while true的效果,别执行,执行了可能卡死

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
for true {
fmt.Printf("这是死循环。\n");
}
}

总结:

  • if的条件里可以赋值
  • if的条件里赋值的变量作用域就在这个if语句里
  • switch后面可以没有表达式,放在case
  • switch不需要break,也可以直接switch多个条件
  • for,if的条件里不需要括号
  • for的条件里可以省略初始条件,结束条件,递增表达式