和很多其它语言一样,Go也支持goto
跳转语句。 在一个goto
跳转语句中,goto
关键字后必须跟随一个表明跳转到何处的跳转标签。 我们使用LabelName:
这样的形式来声明一个名为LabelName
的跳转标签,其中LabelName
必须为一个标识符。 一个不为空标识符的跳转标签声明后必须被使用至少一次。
一条跳转标签声明之后必须立即跟随一条语句。 如果此声明的跳转标签使用在一条goto
语句中,则当此条goto
语句被执行的时候,执行将跳转到此跳转标签声明后跟随的语句。
一个跳转标签必须声明在一个函数体内,此跳转标签的使用可以在此跳转标签的声明之后或者之前,但是此跳转标签的使用不能出现在此跳转标签声明所处的最内层代码块之外。
下面这个例子使用跳转标签声明和goto
跳转语句来实现了一个循环:
package main import "fmt" func main() { i := 0 Next: // 跳转标签声明 fmt.Println(i) i++ if i < 5 { goto Next // 跳转 } }
上面刚提到了一个跳转标签的使用不能出现在此跳转标签声明所处的最内层代码块之外,所以下面的代码片段中的跳转标签使用都是不合法的。
package main func main() { goto Label1 // error { Label1: goto Label2 // error } { Label2: } }
另外要注意的一点是,如果一个跳转标签声明在某个变量的作用域内,则此跳转标签的使用不能出现在此变量的声明之前。 关于变量的作用域,请阅读后面的文章代码块和作用域
下面这个程序编译不通过:
package main import "fmt" func main() { i := 0 Next: if i >= 5 { // error: goto Exit jumps over declaration of k goto Exit } k := i + i fmt.Println(k) i++ goto Next Exit: // 此标签声明在k的作用域内,但 // 它的使用在k的作用域之外。 }
刚提到的这条规则可能会在今后放宽。 目前,有两种途径可以对上面的程序略加修改以使之编译通过。
第一种途径是缩小变量k
的作用域:
func main() { i := 0 Next: if i >= 5 { goto Exit } // 创建一个显式代码块以缩小k的作用域。 { k := i + i fmt.Println(k) } i++ goto Next Exit: }
第二种途径是放大变量k
的作用域:
func main() { var k int // 将变量k的声明移到此处。 i := 0 Next: if i >= 5 { goto Exit } k = i + i fmt.Println(k) i++ goto Next Exit: }
包含跳转标签的break
和continue
语句
一个goto
语句必须包含一个跳转标签名。 一个break
或者continue
语句也可以包含一个跳转标签名,但此跳转标签名是可选的。 包含跳转标签名的break
语句一般用于跳出外层的嵌套可跳出流程控制代码块。 包含跳转标签名的continue
语句一般用于提前结束外层的嵌套循环流程控制代码块的当前循环步。
如果一条break
语句中包含一个跳转标签名,则此跳转标签必须刚好声明在一个包含此break
语句的可跳出流程控制代码块之前。 我们可以把此跳转标签名看作是其后紧跟随的可跳出流程控制代码块的名称。 此break
语句将立即结束此可跳出流程控制代码块的执行。
如果一条continue
语句中包含一个跳转标签名,则此跳转标签必须刚好声明在一个包含此continue
语句的循环流程控制代码块之前。 我们可以把此跳转标签名看作是其后紧跟随的循环流程控制代码块的名称。 此continue
语句将提前结束此循环流程控制代码块的当前步的执行。
下面是一个使用了包含跳转标签名的break
和continue
语句的例子。
package main import "fmt" func FindSmallestPrimeLargerThan(n int) int { Outer: for n++; ; n++{ for i := 2; ; i++ { switch { case i * i > n: break Outer case n % i == 0: continue Outer } } } return n } func main() { for i := 90; i < 100; i++ { n := FindSmallestPrimeLargerThan(i) fmt.Print("最小的比", i, "大的素数为", n) fmt.Println() } }
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/17652663.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2021-08-23 golang代码生成器