目录
简介
Golang 拥有非常严格的代码缩进规则
声明一个变量,但不使用也会报错
Go的 关键字和标识符
关键字
预定义标识符
Golang的变量
声明变量
var num1 int //声明一个int 类型变量
var str1 string //声明一个string 类型变量
var b1 bool //声明一个bool 类型变量
初始化变量
Go语言声明变量就会自动对变量对应的内存区域进行初始化。每个变量会被初始化成其类型的默认
值。如:整型和浮点型变量的默认值为0。字符串变量的默认值为空字符串“"。布尔型变量默认为false。 切片、函数、指针变量的默认为nil.
初始化
var num1 int = 10
var str1 string = "abc"
var b1 bool = false
变量类型可以省略,让其自动推导
var num1 = 10
var str1 = "abc"
var b1 = false
短声明,省略var关键字,使用 :=
num1 := 10
str1 := "abc"
b1 := false
需要注意,短声明初始化方式只能使用在函数内部。
匿名变量
func GetStringAndInt() (string, int) {
return "abc", 10
}
func main() {
_, n1 := GetStringAndInt() //_ 就代表匿名变量
}
Golang 常量
常量在程序编译阶段就确定值,运行时则无法改变。Golang中,常量可以是数值类 型(包括整型、浮点型和复数类型)、布尔类型、 字符串
const constvar1 = 1
const constvar2 = "abc"
const constvar3 = false
const 声明的变量不使用不会报错
iota
iota可以认为是一个可被编译器修改的常量,它默认开始值是θ,每调用一次加1。遇到const 关键字时被重置为0。
const(
c_index2 = iota //此iota每被使用一次就自增1
c_index3 = iota
c_index4 = iota
)
fmt.Println(c_index2) //0
fmt.Println(c_index3) //1
fmt.Println(c_index4) //2
使用 _ 跳过
---------------------------------------------
const (
c_index2 = iota //此iota每被使用一次就自增1
c_index3 = iota
_ //通过 _ 跳过
c_index4 = iota
)
fmt.Println(c_index2) //0
fmt.Println(c_index3) //1
fmt.Println(c_index4) //3
iota 中间插队
const (
c_index2 = iota //此iota每被使用一次就自增1
c_index3 = 100
c_index4 = iota
)
fmt.Println(c_index2) //0
fmt.Println(c_index3) //100
fmt.Println(c_index4) //2
字符串
Golang 中字符串是一个任意字节的常量序列 []byte
Golang中,字符串字面量使用双引号”“ 或者反引号 ·· 来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行。反引号用来创建原生的字符串字面量,可能由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串则多用于书写多行消息,HTML以及正则表达式。
str1 := "abcdefg"
str2 :=
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
</html>`
字符串的连接
golang里面的字符串都不可变,每次运算都会产生一个新的字符串, 所以会产生很多临时的无用的字符
串,不仅没有用,还会给GC带来额外的负担
使用 +=
str1 := "abc"
str1 += "efg"
使用bytes.Buffer
var buf bytes.Buffer
buf.WriteString("abc")
buf.WriteString("123")
buf.WriteString("efg")
fmt.Printf("buf.String(): %v\n", buf.String()) //buf.String(): abc123efg
字符串切割
[m:n) 遵循左闭右开
str := "0123456789"
str_len := len(str) //10
fmt.Printf("len(str): %v\n", len(str))
fmt.Printf("str: %s\n", str[0:]) // 0123456789 默认到结尾
fmt.Printf("str: %s\n", str[:str_len]) // 0123456789 默认到结尾
fmt.Printf("str: %s\n", str[0:str_len]) // 0123456789 [m:n) 左闭右开
fmt.Printf("str: %s\n", str[0:3]) // 012
字符串常用函数
运算符
大部分运算符与大多数语言相同,
++ (自增) 和-- (自减)在Golang 是单独的语句,并不是运算符。
不能这样使用,编译报错
num1 := 0
fmt.Printf("num1: %v\n", num1++)
修改为
num1 := 0
num1++
fmt.Printf("num1: %v\n", num1)
Golang 流程控制语句
条件判断语句
初始变量可以声明在布尔表达式里面,注意其作用域
if cond := true; cond != true {
fmt.Println("hello")
} else {
fmt.Println("world")
}
和C/C++不同,不能使用 0/1 作为条件判断
//编译报错
if 1 {
fmt.Println("hello")
}
使用if注意点:
- 不需使用括号将条件包含起来
- 大括号{}必须存在,即使只有一行语句
- 左括号必须在if或else的同一行
- 在if之后,条件语句之前,可以添加变量初始化语句,使用; 进行分隔
Switch 语句
和C/C++不同,默认只会进入一个case,不需要手动break
day := 8
switch day {
case 1:
fmt.Println("星期一")
case 2:
fmt.Println("星期二")
case 3:
fmt.Println("星期三")
case 4:
fmt.Println("星期四")
case 5:
fmt.Println("星期五")
case 6:
fmt.Println("星期六")
case 7:
fmt.Println("星期日")
default:
fmt.Println("错误")
}
如果需要进行向下匹配,可以使用 fallthrough 关键字
打印 星期一 星期二
day := 1
switch day {
case 1:
fmt.Println("星期一")
fallthrough
case 2:
fmt.Println("星期二")
case 3:
fmt.Println("星期三")
case 4:
fmt.Println("星期四")
case 5:
fmt.Println("星期五")
case 6:
fmt.Println("星期六")
case 7:
fmt.Println("星期日")
default:
fmt.Println("错误")
}
还可以匹配多个条件
day := 3
switch day {
case 1, 2, 3, 4:
fmt.Println("星期一到星期四")
case 5:
fmt.Println("星期五")
case 6:
fmt.Println("星期六")
case 7:
fmt.Println("星期日")
default:
fmt.Println("错误")
}
case 以表达式作为条件
score := 99
switch {
case score > 90:
fmt.Println("优秀")
case score > 80:
fmt.Println("良好")
case score > 70:
fmt.Println("不错")
case score > 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
也可以多条件匹配
score := 99
switch {
case score > 90, score > 80, score > 70:
fmt.Println("挂科了")
case score > 60:
fmt.Println("你挂科了")
default:
fmt.Println("你真挂科了")
}
swtich注意点:
- 支持多条件匹配
- 不同的case之间不使用break分隔,默认只会执行一个case 。
- 如果想要执行多个case,可以使用fallthrough 关键字,也可用break终止。
- 分支还可以使用表达式,例如: age > 18
循环语句
go语言中的循环只有for循环 和 for range(范围for),去除了while、do while 循环。
死循环
for true {
fmt.Println("hello")
}
for range
Golang 中可以使用for range 遍历数组、切片、字符串、map 及通道(channel) 。
通过for range 遍历的返回值:
1.数组、切片、字符串返回索引和值。
2. map返回键和值。
3.通道(channel)只返回通道内的值。
for range 遍历数组:
arr := [5]int{
1, 2, 3, 4, 5}
for index, v := range arr {
fmt.Printf("index: %v ", index)
fmt.Printf("v: %v\n", v)
}
// index: 0 v: 1
// index: 1 v: 2
// index: 2 v: 3
// index: 3 v: 4
// index: 4 v: 5
// index: 4 v: 5
for range 遍历map:
mp1 := make(map[string]string)
mp1["apple"] = "苹果"
mp1["pear"] = "梨"
mp1["cherry"] = "樱桃"
for key, val := range mp1 {
fmt.Printf("key: %v ", key)
fmt.Printf("val: %v\n", val)
}
// key: pear val: 梨
// key: cherry val: 樱桃
// key: apple val: 苹果
break
- 单独在select中使用break和不使用break没有啥区别。
- 单独在表达式switch语句,并且没有fallthough,使用break和不使用break没有啥区别。
- 单独在表达式switch语句,并且有fallthough,使用break能够终止fallthough后面的case语句的执行。
- 带标签的break,可以跳出多层select/ switch 作用域。让break更加灵活,写法更加简单灵活,不需要使用控制变量-一层层跳出循环, 没有带break的只能跳出当前语句块。