goLang
小技巧
- 修改了vscode的tasks.json文件的配置,控制台执行 command + shift + B 可以代替执行go run file.go,多个文件的时候更实用
语言结构 1
2
3
4
5
6
7
8
9// hello.go
package main // 非注释的第一行,指定包名
import "fmt" // fmt 包实现了格式化 IO(输入/输出)的函数
func main() { // 程序开始执行的函数
fmt.Println("hello go") // 相当于fmt.Print("hello, go\n")
}
// 执行 go run hello.go
- 不能使用单引号
- package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包
- main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)
- 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,可以被外部包的代码所使用;以小写字母开头,是在包的内部可见可用
- “{”不能放在单独的一行
基础语法
- 一行代表一个语句结束,不需要分号;一行写多个语句时,用分号区分
数据类型
数据类型的出现是为了把数据分成所需内存大小不同的数据,充分利用内存
- 布尔型: true false
- 数字类型: 整型 int(uint8、uint16、uint32、uint64、 int8、 int16、 int32、 int64),浮点型 float32(IEEE-754 32位浮点型数)、float64(IEEE-754 64位浮点型数)、complex64(32 位实数和虚数)、 complex128(64 位实数和虚数)和其他 byte(类似 uint8)、rune(类似 int32)、uint(32 或 64 位)、int(与 uint 一样大小)、 uintptr(无符号整型,用于存放一个指针)
- 字符串类型
- 派生类型:指针(Pointer)、数组、结构化(struct)、Channel 类型、函数类型、切片类型、接口类型(interface)、Map类型
Go语言变量 1
var b, c int = 1, 2
第一种,指定变量类型:类型写在最后,未指定初始值时,初始值:数值类型为0、布尔类型为false、字符串为””、以下几种为nil:
1
2
3
4
5
6var a *int
var a []int
var a map[string] int
var a chan int
var a func(string) int
var a error // error 是接口第二种,根据值自行判定变量类型
第三种,省略 var(初始化声明,是使用变量的首选形式,但只能被用在函数体内), 注意 := 左侧如果没有声明新的变量,就产生编译错误
1
2
3var intVal int
intVal :=1 // 重复声明intVal,会产生编译错误
intVal,intVal1 := 1,2 // 此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句多变量声明
1
2
3
4
5// 声明全局变量
var (
vname1 v_type1
vname2 v_type2
)值类型和引用类型:值类型存储在栈中,可以通过&i 来获取变量 i 的内存地址,内存地址会根据机器的不同而有所不同
- 如果声明了一个局部变量却没有在相同的代码块中使用它,会得到编译错误;全局变量是允许声明但不使用的
- 如果想要交换两个变量的值,则可以简单地使用 a, b = b, a,两个变量的类型必须是相同
- 空白标识符 _ 是一个只写变量(被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃),你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。
Go语言常量(在程序运行时,不会被修改的量) 1
2
3
4
5
6
7const LENGTH int = 10
const ( // 常量用作枚举
Unknown = 0
Female = 1
Male = 2
)
- 常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过
- iota,特殊常量,可以认为是一个可以被编译器修改的常量
运算符
&
返回变量存储地址*
指针变量(保存的是一个地址值)
条件判断语句
- if、if else、switch、select(select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行)
- 注意:Go 没有三目运算符,所以不支持 ?: 形式的条件判断
循环控制语句
- break、continue,还有个goto(将控制转移到被标记的语句)
函数 1
2
3func function_name( [parameter list] ) [return_types] {
函数体
}
- 标准库函数有 len()
数组 1
2// 不指定长度
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
指针
- 一个指针变量通常缩写为 ptr
- nil 指针称为空指针
结构体 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
// 创建一个新的结构体
fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})
// 也可以使用 key => value 格式
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})
// 忽略的字段为 0 或 空
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
}
- Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17numbers := []int{0,1,2,3,4,5,6,7,8} // 初始化
// 切片
fmt.Println("numbers ==", numbers)
fmt.Println("numbers[0] == ", numbers[0])
fmt.Println("numbers[:2] == ", numbers[:2])
fmt.Println("numbers[1:2] == ", numbers[1:2])
// append()
numbers = append(numbers, 2,3,4)
// copy()
copy(des, src)
var identifier []type // 声明一个未指定大小的数组来定义切片
slice1 := make([]type, len) // 用make()函数来创建切片
make([]T, length, capacity) // 也可以指定容量,其中capacity为可选参数切片是可索引的,并且可以由 len() 方法获取长度
- 切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少
- 一个切片在未初始化之前默认为 nil,长度为 0
- 切片截取,跟python差不多[lower-bound:upper-bound]
Go 语言范围(Range)
- range 关键字在数组和切片中返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值
Go 语言Map(集合)
Map 是一种无序的键值对的集合
1
2
3
4
5
6
/* map 关键字,声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对
1
2
3
4
5
6
7
8
9
10
11var countryCapitalMap map[string]string /*创建集合 */
countryCapitalMap = make(map[string]string)
/* map插入key - value对,各个国家对应的首都 */
countryCapitalMap [ "France" ] = "巴黎"
countryCapitalMap [ "Italy" ] = "罗马"
countryCapitalMap [ "Japan" ] = "东京"
countryCapitalMap [ "India " ] = "新德里"
/* delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key */
delete(countryCapitalMap, "France")
Go 语言递归就是调用自己,不知道后续是否有优化算法
Go 语言类型转换 1
type_name(expression)
Go 语言接口
- interface 是一种数据类型
Go 并发
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的,自行了解下 goroutine 与线程的区别
1
go 函数名( 参数列表 )
通道(channel)是用来传递数据的一个数据结构
1
ch := make(chan int)
开发工具
- LiteIDE、Eclipse(自行搜刮)