基础知识

变量

变量声明有三种方式:

  1. 可变量: var <name> <type> [ = <initial value>]

  2. 常量: const <name> <type> = <initial value>

  3. 简写方式,只能用于函数中,不能在全局环境下使用 <name> := <value>

1
2
3
4
5
6
7
8
9
import ("fmt")
func main() {
	var n int32 = 100
	var n1 int32
	n1 = 200
	const cn string = "hello world !"
	n2 := 300
	fmt.Println(n, n1, n2, cn)
}
100 200 300 hello world !

指针变量: var pr *int 整型指针,表示该指针指向的内存中存放的是一个整型数据

1
2
3
4
5
6
7
import ("fmt")
func main() {
	var pr *int
	var n = 100
	pr = &n
	fmt.Println(pr, *pr)
}
0xc0000b6008 100

n 是个整型变量,里面存储了一个 100 , pr = &n 意思是将 pr 指向 n 的地址,该地址 了存储了 100 的那块内存,所以 pr 实际上是一个内存中的16进制的地址值,对其取值 *pr 得到 100。

指针变量做为函数参数:

1
2
3
4
5
6
7
8
import ("fmt")
func test_pr(pr *int) {
	fmt.Println(pr, *pr)
}
func main() {
	var n int = 100
	test_pr(&n) // 将地址传进去
}
0xc0000180b8 100

函数

声明:

func <name>(arg1 <type>, arg2 <type>) <return type>

多个返回值:

func <name>(arg1 <type>, arg2 <type>) (<type1>, <type2>)

指定返回的变量名(此时 return 后面不需要明确返回变量):

func <name>(arg1 <type>, arg2 <type>) (a, b <type>)

测试:

 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
import ("fmt")
func fn1() {
	fmt.Println("fn1: 没有参数,没有返回值。")
}
func fn2(a int, b int) int {
	fmt.Println("fn2: 一个返回值,返回两个参数的和。")
	return a + b
}

func fn3(a int, b int) (int, int) {
	fmt.Println("fn3: 两个返回值,返回两个参数的和与差。")
	return a + b, a - b
}

func fn4(a int, b int) (x int, y int) {
	fmt.Println("fn4: 两个返回值且指定返回变量名,返回的两个变量名不能和参数同名。")
	x = a + 1
	y = b + 1
	return
}
func fn5(a, b int) (x, y int) {
	fmt.Println("fn5: 同类型合并。")
	x = a * 10
	y = b * 10
	return
}

func main() {
	fn1()
	r2 := fn2(1, 2)
	r31, r32 := fn3(1, 2) // 两个返回值需要用两个变量来接受
	r41, r42 := fn4(1, 2)
	r51, r52 := fn5(1, 2)
	fmt.Println(r2, r31, r32, r41, r42, r51, r52)
}
fn1: 没有参数,没有返回值。
fn2: 一个返回值,返回两个参数的和。
fn3: 两个返回值,返回两个参数的和与差。
fn4: 两个返回值且指定返回变量名,返回的两个变量名不能和参数同名。
fn5: 同类型合并。
3 3 -1 2 3 10 20

TIP

注意: fn4, fn5 中 x, y 变量的使用,并没有采用 声明方式去赋值,如果这样 x := a + 1 会报错,因为返回值输写方式里面已经对 x, y 进行了声明。

另外,函数 fn1() 调用时不能 r1 := fn1() 因为它没有返回值,并且 fn3, fn4, fn5 在 调用的时候,如果要接收它们的返回值需要这样 r31, r32 = fn3(1,2) 要用两个变量去接 收。

函数做参数func fn(fn func([args...]) string) {...}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import ("fmt")

// 接收一个函数做为参数,该函数返回值为 int 同时接受两个 Int 参数
func getFn(sum func(int, int) int, b int) int {
	var a = 100
	return sum(a, b)
}

func sum(a int, b int) int {
	return a + b
}

func main() {
	c := getFn(sum, 10)
	fmt.Println(c)
}
110

控制流

控制语句:

if, else if, else, switch, for, defer

defer <statement> 延迟执行的语句,它们会在函数退出之前被执行。

 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
import ("fmt")

var a int = 0
func reset() {
	a = 0
	fmt.Println("run before main exit, reset a value, a =", a)
}

func main() {
	defer reset()

	for {
		if a == 1 {
			fmt.Println("in for, if a = 1")
		} else if a == 2 {
			fmt.Println("in for, else if a = 2")
		} else if a == 10 {
			fmt.Println("in for, else if a = 10, end.")
			return
		} else {
			fmt.Println("in for, else, a =", a)
		}

		switch a {
			case 3:
			fmt.Println("in for, switch case, a = 3")
			case 4:
			fmt.Println("in for, switch case, a = 4")
			default:
			fmt.Println("in for, switch default, a =", a)
		}

		a += 1
	}
}
in for, else, a = 0
in for, switch default, a = 0
in for, if a = 1
in for, switch default, a = 1
in for, else if a = 2
in for, switch default, a = 2
in for, else, a = 3
in for, switch case, a = 3
in for, else, a = 4
in for, switch case, a = 4
in for, else, a = 5
in for, switch default, a = 5
in for, else, a = 6
in for, switch default, a = 6
in for, else, a = 7
in for, switch default, a = 7
in for, else, a = 8
in for, switch default, a = 8
in for, else, a = 9
in for, switch default, a = 9
in for, else if a = 10, end.
run before main exit, reset a value, a = 0

Goroutine & Channel

1
2
3
4
import ("fmt")
func main() {
	fmt.Println("xxxxx")
}
xxxxx

完整脑图

下载地址: Golang

/img/go/Golang.svg

问题

go get i/o timeout ?

1
2
3
4
5
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

# 设置不走 proxy 的私有仓库,多个用逗号相隔(可选)
go env -w GOPRIVATE=*.gitlab.com