for-range循环
在其他编程语言中,我们通常会对map进行迭代。同样的,Go语言给我们提供了for-range循环,它也是一种迭代结构。其语法如下:
for key,value :=range 复合变量值{ //....逻辑语句 }
遍历数组
首先,我们需要了解数组的定义,与普通变量定义一样,只是多了一个"[]"号。
//无初始值定义 var num []int //有初始值定义 var num =[]int{1,2,3,4,5,6,7,8,9,0}
下面,我们来展示如何遍历上面的数组。代码如下所示:
//声明数组情况下的遍历 var num =[]int{1,2,3,4,5,6,7,8,9,2} for key,value :=range num{ fmt.Println("key=",key,"value=",value) } //直接遍历临时创建的数组 for key,value :=range []int{1,2,3,4,5,6,7,8,9,2}{ fmt.Println("key=",key,"value=",value) }
遍历字符串
与某些语言一样,Go语言的字符串其实也是单个字符组成的数组,我们同样可以在程序中,对Go字符串进行遍历。代码如下:
var name string="liyuanjinglyj" for key,value :=range name{ fmt.Printf("key=%d , value=%c \n",key,value) }
遍历map
对于map就更简单了,在遍历的时候,key,value正好对应其键值对。具体遍历方式如下所示:
//获取key,value m:=map[string] string{ "name":"liyuanjing", "age":"29", } for key,value :=range m{ fmt.Printf("key=%s , value=%s \n",key,value) } //只获取value m:=map[string] string{ "name":"liyuanjing", "age":"29", } for _,value :=range m{ fmt.Println(value) }
第二种方式中的key变更为了"_",这个下划线就是匿名变量,可以理解为占位符。匿名变量本身不参与空间分配,也不会占用一个变量的名字。同样的,也可以对value使用匿名变量,只获取key。
遍历通道(channel)
什么是通道,我们后面介绍,这里我们直接来定义一个通道,看看如何进行遍历。
a := make(chan int) go func() { a <- 1 a <- 2 a <- 3 close(a) }() for v := range a { fmt.Println(v) }
上面代码的逻辑:
1.创建一个整型类型的通道并实例化
2.通过关键字go启动一个goroutine
3.将数字传入通道,实现的功能是往通道中推送数据123
4.结束并关闭通道
5.用for-range循环对通道a进行遍历,即不断地从通道中接受数据直到通道被关闭
switch-case语句
Go语言改进了C语言的switch-case语句,表达式不必为常量,甚至不必为整数。而且case与case之间是独立的代码段,不需要通过break语句跳出当前case,以避免执行到下一个case。
var name ="周杰伦" switch name { case "周杰伦": fmt.Println("歌手") case "王昭君": fmt.Println("和亲使者") default: fmt.Println("查无此人") }
上面代码运行结果只会打印歌手,没有break也不会执行下面的语句,这一点博主觉得Go语言设计的不错。
一个分支多个值
当然,其实switch-case语句中的case,并不仅仅只能选择一个词,比如有的明星,即使演员又是歌手,难道用if and进行判断?
var name ="歌手" switch name { case "歌手","演员": fmt.Println("易烊千玺") case "作家": fmt.Println("盐野七生") default: fmt.Println("啥也不是") }
分支表达式
case语句不仅仅可以跟常量,也可以和if一样添加表达式。示例如下:
var num =22 switch{ case num>0 && num==22 : fmt.Println("是22没错") default: fmt.Println("啥也不是") }
如上面代码所示,switch在这种情况下,不必再需要加用于判断的变量。
goto语句
Go语言最知名的语句,就是goto语句。通过goto语句可以直接跳转到指定的标签,进行代码之间的无条件跳转。另外,goto语句也可以用作跳出循环,避免重复退出等场景。
在前文中,我们通过break直接跳出到最外层的循环,现在我们改变当时的代码,使用goto来实现结束循环。
func main() { var i, j int for i = 1; i < 100; i++ { for j = 0; j < i; j++ { fmt.Println(j) if i > 10 { goto endTag } } } return endTag: fmt.Println("循环结束") }
如上面代码所示,我们直接指定跳转到endTag标签处,这种标签也是自己自定义命名的。
不过需要注意的是,endTag标签上面有一个return,这是因为不满足条件则不执行endTag标签语句,不然,哪怕结束,程序也会顺序执行。
goto这么方便,读者想到了哪些应用场景呢?
相信读者都在其他语言中,抛出过各式各样的异常,特别是很多网络请求其实异常差不多,但遇到一个抛一个是不是非常烦?
而goto就很简单了,可直接跳到指定异常,这样用一个异常就可以解决所有相同异常。
err :=getEmail() if err !=nil{ goto endTag } err =getUser() if err !=nil{ goto endTag } endTag: fmt.Println(err) //异常处理
这里,我们假设有2个方法,获取用户名与邮箱,但其实他们抛出的异常都相同,那么可以直接都跳转到指定的标签处,进行相同异常的处理。而不必每个都抛出异常写一遍。