go 泛型
if 语法
基本写法如下所示:
if 表达式1 {
分支1
} else if 表达式2 {
分支2
} else {
分支3
}
其中else if
和 else
都是可选的,这个基本所有的语言都是这样的,可以根据实际需要进行选择,例如如下所示也是可以的:
if 表达式1 {
分支1
}
在 if 表达式之前添加一个执行语句,如下所示,在score >= 90
之前,有一个score := 80
的赋值语句,注意的是,变量 score 的作用域只在 if 语句块中,外部是没法访问到的:
func main() {
if score := 80;score >= 90 {
fmt.Println("A")
} else if score >= 70 {
fmt.Println("B")
} else {
fmt.Println("C")
}
fmt.Println(score) // sorce没有定义
}
swich case 分支结构
和其它语言一样,执行规则是从上至下逐一比较,直到匹配为止就进入该分支执行相应的代码。不同的是,在 go 语言中不需要再加 break,默认就是 break。如果我们需要执行后面的 case,可以使用 fallthrough
。
func switchDemo1() {
finger := 3
switch finger {
// 比较是否相等
case 1:
fmt.Println("大拇指")
case 2:
fmt.Println("食指")
case 3:
fmt.Println("中指")
case 4:
fmt.Println("无名指")
case 5:
fmt.Println("小拇指")
default:
fmt.Println("无效的输入!")
}
}
在go语言中,case
语句后面,可以是多个值,用英文逗号分隔,只要等于其中的任意一个就可以:
func testSwitch3() {
// 变量n,只在switch语句块中生效
switch n := 7; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
case 2, 4, 6, 8:
fmt.Println("偶数")
default:
fmt.Println(n)
}
}
还可以在case语句里使用表达式,年龄在25到35之间的时候,输出"好好工作":
func switchDemo() {
age := 30
switch {
case age < 25:
fmt.Println("好好学习吧")
case age > 25 && age < 35:
fmt.Println("好好工作吧")
case age > 60:
fmt.Println("好好享受吧")
default:
fmt.Println("活着真好")
}
}
go语言中,默认情况下,case后面会自动break,有时候想要继续执行接下来的case,可以使用fallthrough语句:
func switchDemo() {
s := "a"
switch {
case s == "a":
fmt.Println("a")
// 执行下一个case
fallthrough
case s == "b":
fmt.Println("b")
case s == "c":
fmt.Println("c")
default:
fmt.Println("...")
}
}
for循环
go语言中,只有两种循环语法,一个是for循环,另外一个是for range循环,for循环的基本格式和其它语言一样,如下所示:
for 初始语句;条件表达式;结束语句{
循环体语句
}
// 例如
func forDemo() {
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}
go语言中,for循环可以省略初始化语句,此时,初始语句后的分号必须要写:
func forDemo2() {
i := 0
// 初始语句后的分号必须要写
for ; i < 10; i++ {
fmt.Println(i)
}
}
还可以,初始化语句和结束语句都省略,相当于 while 循环:
func forDemo3() {
i := 0 // i作用域于函数
// 相当于while语句
for i < 10 {
fmt.Println(i)
i++
}
}
全部忽略的时候,就相当于死循环:
// 语句为空的时候
for {
fmt.println("hello world")
}
for range循环
主要是用于遍历数组、切片、字符串、map、通道(channel)。如下所示,遍历切片:
func main() {
var cityArr = [...]string{0:"北",1:"上",2:"广",3:"深"}
for index,value:=range cityArr {
fmt.Println(index,"=>",value)
}
}
遍历的时候,可以不需要value值:
func main() {
var cityArr = [...]string{0:"北",1:"上",2:"广",3:"深"}
// 只需要一个index即可
for index:=range cityArr {
fmt.Println(index)
}
}
还可以不需要index,如下所示:
func main() {
var cityArr = [...]string{0:"北",1:"上",2:"广",3:"深"}
for _,value:=range cityArr {
fmt.Println(value)
}
}
break、continute、goto跳出循环
break 跳出循环,这个和其它语言是一样的逻辑:
func breakDemo() {
for i := 0; i < 5; i++ {
if i == 2 {
break
}
fmt.Println(i) // 输出:0,1
}
}
continute 跳出本次循环和其它语言也一样:
func continueDemo() {
for i := 0; i < 5; i++ {
if i == 2 {
continue
}
fmt.Println(i) // 输出:0,1,3,4,5
}
}
goto 跳到指定的标签,和其它语言也一样,不过不常用:
// 输出:0-1,0-2,结束for循环
func gotoDemo() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 设置退出标签
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 标签
breakTag:
fmt.Println("结束for循环")
}
label 语法跳出外层循环
正常情况下,break 只能跳出当前循环体里的循环,如果有两层循环嵌套,想要在内层循环里跳出外层循环,也是可以实现的。
如下所示,L 名称是可以随便定义,当 i 等于 3 的时候,外层循环就直接跳出了:
func LabelForDemo() {
L:
for i := 0; i < 8; i++ {
fmt.Println(i) // 输出0,1,2,3
for j := 0; j < 8; j++ {
if i == 3 {
break L
}
}
}
}
这个语法也是用在 switch 里的,默认情况下,switch 里的 break 只能跳出 switch:
func LabelSwitchDemo() {
L:
for i := 0; i < 8; i++ {
switch i {
case 4:
break L
default:
fmt.Println(i) // 输出0,1,2,3
}
}
}
这个语法还可以用在 select 多路复用里,一秒钟之后,解除阻塞,breck 循环
func LabelSelectDemo() {
ch := make(chan int, 1)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
L:
for i := 0; i < 8; i++ {
fmt.Println(i) // 输出0
select {
case <-ch:
case <-ctx.Done():
break L
}
}
}