Go语言学习 七 流程控制之if-else

    xiaoxiao2024-10-05  90

    本文最初发表在我的个人博客,查看原文,获得更好的阅读体验


    Go中关于流程控制方面主要有if-else,for循环,switch。另外,Go中还多了一种新的控制结构select,这种结构包含一个类型开关和一个多路通信复用器;if和switch接受类似for的可选初始化语句;break,continue和goto语句采用可选标签来标识要中断或继续以及要跳转的内容;与C相比,Go的控制结构语法也有些区别:没有小括号,并且控制体必须包含在一对大括号中。

    关于select的用法,将在后续关于并发的文章中讲。

    一 if语句

    if表达式外无需小括号 ( ) ,而大括号 { } 则是必须的。强制使用大括号是为了鼓励将简单的if语句拆分成多行。这是一个好习惯,特别是当控制体中包含return或break语句时。

    在Go中,一个简单的if语句如下:

    if x > 0 { return y; }

    示例:

    package main import ( "fmt" "math" ) func main() { fmt.Println(sqrt(16)) fmt.Println(sqrt(-9)) } func sqrt(x float64) string { if x < 0 { return sqrt(-x) + "i" } return fmt.Sprint(math.Sqrt(x)) }

    二 简短语句

    if 语句可以在条件表达式前执行一个简单的语句。该语句声明的变量作用域仅在 if 之内。

    package main import ( "fmt" "math" ) func main() { fmt.Println( pow(3, 2, 10), pow(3, 3, 20), ) } func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } // return v // 错误:undefined: v return lim }

    上述示例中的第16行中,语句v := math.Pow(x, n)会优先求值。然后再拿结果进行比较。

    类比一下:Java中类似语法可以这样写:

    int r; if ((r = Math.round(x) > 0) { return r; }

    在 if 的简短语句中声明的变量同样可以在任何对应的 else 块中使用。 例如,将上述示例中的pow函数改为:

    func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } else { fmt.Printf("pow(%v, %v, %v)超出lim参数范围,结果将被截取为%v\n", x, n, lim, lim) } // return v // 错误:undefined: v return lim }

    在Go中,如果if语句之后没有进入下一个语句,则意味着该if控制体中最后一行是 break、continue、goto或者return(这里省略了非必须的else语句):

    f, err := os.Open(name) if err != nil { return err } codeUsing(f)

    联想:在Java中,break、continue只能出现在循环体中,而goto是保留关键字。

    下面是一种常见的情况,其中代码必须处理防止一系列错误。由于错误情况将以return语句结束,因此之后的代码不需要else语句。

    f, err := os.Open(name) if err != nil { return err } d, err := f.Stat() if err != nil { f.Close() return err } codeUsing(f, d)

    类比一下:这种做法在Java和其他语言中也很常见,避免过多的if-else嵌套。

    三 重新声明和重新赋值

    上一节中的最后一个示例演示了:=简短声明的工作原理。调用os.Open的声明:

    f, err := os.Open(name)

    该语句声明了两个变量f和err。几行之后,调用f.Stat:

    d, err := f.Stat()

    看起来好像是声明了d和err。但请注意,err出现在两个语句中。这种重复是合法的:err是由第一个语句声明的,但在第二个语句中仅是重新赋值而已。这意味着对f.Stat的调用使用上面声明的现有err变量,并只是给它一个新值。

    在:=声明中,即使已经声明变量v,也可能再次出现变量v,前提是:

    此声明与v的现有声明在同一范围内(如果v已在外部作用域中声明,当前声明将创建一个新变量)初始化中的相应的值可分配给v,并且声明中至少有一个其他变量是新声明的。

    这种特殊的特性纯粹是为了实用,能够简单的复用同一个变量,而且这种用法很常见。

    值得注意的是,在Go中,函数参数和返回值的作用域范围与函数体相同,即使它们在大括号之外的词法上出现。

    参考: https://golang.org/doc/effective_go.html#if https://golang.org/ref/spec#If_statements

    最新回复(0)