这是我参与 [第五届青训营] 伴学笔记创作活动的第1天
Go语言基础
简介
Go语言最主要的特性:
- 自动垃圾回收
- 更丰富的内置类型
- 函数多返回值
- 错误处理
- 匿名函数和闭包
- 类型和接口
- 并发编程
- 反射
- 语言交互性
代码注意要点
- 程序入口必须是main包的main函数
- 每行结尾不必打 ;
- if 表达式, for 表达式不必打 ()
- 定义的变量等必须要使用,否则编译不通过(全局变量除外)
- 包中写的函数或变量名若首字母大写,则包外可访问,否则只能包内访问
- ......
Go语言数据类型
- bool类型: true false
- 数字类型: byte int int8 int16 int32 rune uint8 uint16 uint32 uint64 int64 uint float32 float64 complex64(32位实数和虚数, 默认值是0+0i) complex128(64位实数和虚数, 默认值是0+0i) uintptr(无符号整型,用于存放指针)
- 字符串类型: 由单个字节连接起来
- 派生类型: 指针、数组、结构体、Channel、函数、切片、接口、Map
Go语言变量与常量
单独声明一个变量
var value1 int
var value2 int = 3
var value3 = 4
声明多个变量
var value1, value2, value3 int
var value4, value5, value6 = 1, 2, 3
简短形式,:=操作符
value1 := 2
value2, value3, value4 := 1, 2, 3
常量声明
const str1 string = "abc"
const str2 = "abcde"
const str3, str4, str5 = "aa", "bb", "cc"
fmt.Printf(len(str2)) //5
fmt.Printf(unsafe.Sizeof(str2)) //16
//string类型在 go 里是个结构, 包含指向底层数组的指针和长度,这两部分每部分都是8个字节,
//所以字符串类型大小为 16 个字节。
const枚举
//iota,特殊常量,可以认为是一个可以被编译器修改的常量,当const关键词出现时,重置为0,每增一行iota+1,可以看做行索引
const (
n1 = iota //0
n2 //1
_ //2,抛弃
n4 //3
n5 = 100 //100
n6 //100, 会延续上一行
n7 = iota //6
)
条件语句
if语句
if(/*表达式*/) {
} else if {
} else {
}
switch 语句
grade := 98
switch {
case grade >= 90:
fmt.Println("A") //不必加break
case grade >= 80:
fmt.Println("B")
case grade >= 70:
fmt.Println("C")
case grade >= 60:
fmt.Println("D")
default:
fmt.Println("E")
}
x := 2
switch x {
default:
fmt.Println("default语句放哪都最后执行")
case 1, 4, 5: //允许的操作
fmt.Println("1.条件语句是false")
fallthrough
case 2:
fmt.Println("2.条件语句是true")
fallthrough //强制执行下一条case语句
case 3:
fmt.Println("3.条件语句是false")
}
select语句
-
select 是 Go 中的一个控制结构,类似于 switch 语句。
-
select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。
-
select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。
-
如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。
循环语句
PS: Go语言的循环只有for关键字
无限循环
for {
}
for true {
}
循环体
for int i = 1; i <= 10; i++ {
}
range : range 可以对数组、字符串、map(集合)、slice(切片)、channel(通道) 迭代循环
num := []int{1, 2, 3, 4, 5}
for index, value := range num{
fmt.Println("num1[", index, "]=", value)
}
fmt.Println(num) //[1 2 3 4 5]
goto 语句
在变量 a 等于 15 的时候跳过本次循环并回到循环的开始语句 LOOP 处:
var a int = 10
/* 循环 */
LOOP: for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
数组
声明数组
var num[10]int
var num[10][10]int //二维数组
声明同时初始化数组
var num[10]string = {"1","2","3"} //其他未声明值为空""
num = []int {1,2,3,4,5}
向二维数组中添加一维数组
arr := [][]int{}
num1 := []int{1, 2, 3, 4, 5}
num2 := []int{5, 4, 3, 2, 1}
arr = append(arr, num1)
arr = append(arr, num2)
指针
value := 9
var ptr *int
ptr = &value
fmt.Println(*ptr) //9
切片
slices := make([]int, 10, 100) //10为数组长度len、100为最大容量cap
s := slices[0:10] //以另一切片或数组 0~10初始化切片
fmt.Println(s[1:2]) //截取切片 :10 0: :
slices = append(slices, 1, 2, 3) //切片添加元素
newSlices := make([]int, len(slices), (2 * cap(slices))) //扩容到两倍
copy(newSlices, slices) //把slices内容拷贝到newSlices
Map(集合)
//map
//var mapTest1 map[string]string //声明
mapTest1 := map[string]string{"1": "own", "2": "two", "3": "three"}
fmt.Println(mapTest1)
mapTest2 := make(map[int]string)
mapTest2[1] = "own"
mapTest2[2] = "two"
mapTest2[3] = "three"
mapTest2[4] = "four"
for key, value := range mapTest2 {
fmt.Printf("%v->%v\n", key, value)
}
number, english := mapTest2[2]
if english {
fmt.Println("存在", number)
} else {
fmt.Println("不存在对应value值")
}
delete(mapTest2, 4) //删除key值对应的key-value对
函数
Go语言的函数可以没有返回值,也可以有多个返回值
普通函数
func 函数名(参数列表) (返回值列表,可无) {
}
func numbers() (int, int, string) {
return 1, 2, "3"
}
对象的成员函数
fuc (object Type) (参数列表) (返回值) {
}
err错误
func sum(f1, f2 float64) (float64, error) {
return f1 + f2, errors.New("加法错误")
}