go语言的基本概念
1. go语言的特性
- 编译型语言 : 先编译再运行(go build),和C一样的特性,速度快(优于java和python这种解释型语言,java先编译后解释再运行,python解释然后运行)
- 垃圾回收 : 自动回收垃圾(不需要手动释放内存),和 java 一样
- 异常处理 : 没有try…catch,用返回值的形式来判断错误
- 交叉编译 : 可以在不同平台编译(windows,linux,mac),完全支持UTF-8编码
- 高并发 : 支持高并发(goroutine),很多情况下不需要考虑锁机制带来的问题(channel)
- 网络编程方便 : 自带了网络编程的接口
- 短语法: 自动变量类型判断(:=),函数简化(func),访问权限机制由标识符(函数名,变量名,常量名)的首字母大小写来决定(大写public,小写private)
- 语言交互性 : go 由 C 语言开发,可以调用c语言(cgo)
2. go的一些概念
环境变量
- GOROOT : go的安装目录
- GOPATH : 工作目录,包含三个子目录 : bin,pkg,src
- GOBIN : 编译后二进制文件的存放路径
- GO111MODULE : 是否开启go mod模式(1.11版本后默认开启)
- GOARCH : 目标平台的架构(amd64,arm)
- GOPROXY : Go 的代理设置,用于下载 Go 的第三方包
一些命令
- go build : 编译go文件,生成可执行文件
- go run : 编译并运行go文件
- go install : 编译并安装包及其依赖项
- go get:动态获取远程代码包及其依赖包,并进行编译和安装
- go mod:用于模块维护,包括初始化模块、添加和更新依赖项等
- go clean:删除编译生成的对象文件和缓存文件
- go fmt:使用 gofmt 重新格式化 Go 包的源代码
- go list:列出包或模块的信息
- go version:打印 Go 的版本信息
- go env:打印 Go 的环境信息
3. go语言的语法
书写规范
- 命名规范:
Go 在命名时以字母或下划线开头,后面跟着零或更多的字母、下划线和数字
Go 不允许在命名时中使用 @、$ 和 % 等标点符号
Go 是一种区分大小写的编程语言,命名以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用 - 代码风格:
Go 语言的代码风格应该简洁、清晰。
Go 语言鼓励使用简短的变量名,尤其是在函数的局部变量。
基本类型
基本类型和java还是有挺多不同的,如下
1
2
3
4
5
6
7
8
9
10
11
12bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr 无符号
byte // uint8 的别名
rune // int32 的别名 类似于java中的char类型
// 表示一个 Unicode 码点
float32 float64 浮点数类型(C中的float和double)
complex64 complex128 // 复数类型(在math包中)他们的零值:
1
2
3
4
5数值类型为:0
布尔类型为:false
字符串为(空字符串):""
// go中没有null的概念
指针、切片、映射、通道、函数和接口等引用类型的零值则是nil变量和常量:
go中常量声明用const
,变量声明用var
或者:=
(短变量声明,在函数体内,不能用于全局变量的声明);
导入包(目录)
go导入包步骤: 先去$GOROOT
下查找,再去$GOPATH
下查找
go导入包 一般用import
关键字,如下
1 | import "fmt" // 单行导入 |
打印
go中打印使用fmt
包,最常用的是Printf
和Println
Printf支持格式化的字符串(在字符串中添加格式说明符如%T,像c语言的printf一样)
Println会自动在末尾添加换行符(和java的System.out.println差不多,只是拼接字符串和变量用的符号不同,java中用的是+
,而go中是,
)
如下:
1 | package main |
go中的格式说明符:
1 | %v:默认格式的值 |
输入
go中输入使用fmt
包,最常用的是Scanf
和Scanln
,同上,Scanln
会自动在末尾添加换行符,Scanf
格式化输入
不同的是,输入需要进行异常处理,如:
1 | package main |
循环
在go中使用for
关键字,go中没有while
,只有for,如下:
1 | for{ |
- for-range
这是Go语言特有的一种的迭代结构,它一般用来遍历数组,slice和map等集合。输出结果:1
2
3
4
5
6
7
8
9
10package main
import(
"fmt"
)
func main() {
arr := [...]int{6, 7, 8}
for i, v := range arr {
fmt.Println(i,v)
}
}1
2
30 6
1 7
2 8
条件语句
if-else,与C语言不同的是,go中的if语句可以添加初始化语句
如下: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
44package main
import "fmt"
func main() {
var sum int
_, err := fmt.Scanln(&sum)
if err != nil {
fmt.Println("输入错误")
}
if i := 8; sum < i {
fmt.Println("执行if语句内的打印")
} else if sum == i {
fmt.Println("执行else-if语句内的打印")
} else {
fmt.Println("执行else语句内的打印")
}
}
```
- switch-case
golang中的`switch`语句与C语言中的`switch`语句类似,但是golang中的`case`语句默认会`break`,不会像C那样没有`break`就一直执行下去
如下:
``` go
package main
import "fmt"
func main() {
var sum int
_, err := fmt.Scanln(&sum)
if err != nil {
fmt.Println("输入错误")
}
switch sum {
case 1:
fmt.Println("这是第1个case语句")
case 2:
fmt.Println("这是第2个case语句")
case 3:
fmt.Println("这是第3个case语句")
default:
fmt.Println("这是第default语句")
}
}fallthrough关键字
switch语句中,如果在执行完每个分支的代码后,还希望继续执行后续分支的代码,可以使用fallthrough关键字来达到目的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package main
import(
"fmt"
)
func main() {
i :=2
switch i {
case 0:
fmt.Printf("0")
case 1:
fmt.Printf("1")
case 2:
fallthrough //fallthrough会强制执行后面的case代码
case 3:
fmt.Printf("3")
default:
fmt.Printf("Default")
}
}
defer关键字
在Go语言中,defer
是一种延迟调用机制,defer
后面的函数只有在当前函数执行完毕后才能执行
如:
1 | package main |
输出结果为:
1 | 这是没有defer关键字的语句 |
当有多个defer
语句时,后面的defer
语句会先执行
如:
1 | package main |
输出结果为:
1 | 开始 |