GO语言学习笔记(与Java的比较学习)(二)

控制结构

if-else:

关键字 if 和 else 之后的左大括号 { 必须和关键字在同一行,如果你使用了 else-if 结构,则前段代码块的右大括号 } 必须和 else-if 关键字在同一行。这两条规则都是被编译器强制规定的。

格式如下:

if condition1 {
    // do something 
} else if condition2 {
    // do something else    
} else {
    // catch-all or default
}

if 可以包含一个初始化语句(如:给一个变量赋值)。这种写法具有固定的格式(在初始化语句后方必须加上分号),例如:

val := 10
if val > max {
    // do something
}

你也可以这样写:

if val := 10; val > max {
    // do something
}

使用简短方式 := 声明的变量的作用域只存在于 if 结构中(在 if 结构的大括号之间,如果使用 if-else 结构则在 else 代码块中变量也会存在)。如果变量在 if 结构之前就已经存在,那么在 if 结构中,该变量原来的值会被隐藏。(我的理解是相当于声明了一个作用域为条件判断结构的局部变量)

测试多返回值函数的错误

Go 语言的函数经常使用两个返回值来表示执行是否成功:返回某个值以及 true 表示成功;返回零值(或 nil)和 false 表示失败

当不使用 true 或 false 的时候,也可以使用一个 error 类型的变量来代替作为第二个返回值:成功执行的话,error 的值为 nil,否则就会包含相应的错误信息(Go 语言中的错误类型为 error: var err error)

如果我们想要在错误发生的同时终止程序的运行,我们可以使用 os 包的 Exit 函数:

if err != nil {
    fmt.Printf("Program stopping with error %v", err)
    os.Exit(1)
}

os包的Exit()会直接终止程序。如果在main包中,则使用return就可以终止程序。

switch

相比较 C 和 Java 等其它语言而言,Go 语言中的 switch 结构使用上更加灵活。Go 的 switch 语句类似于 C、C++、Java、JavaScript 和 PHP 中的,不过 Go 只运行选定的 case,而非之后所有的 case。 实际上,Go 自动提供了在这些语言中每个 case 后面所需的 break 语句。 除非以 fallthrough 语句结束,否则分支会自动终止。

它接受任意形式的表达式:

switch var1 {
     case val1:
        ...
    case val2:
        ...
    default:
        ...
}
  • 当代码块只有一行时,可以直接放置在 case 语句之后。

  • 您同样可以使用 return 语句来提前结束代码块的执行。当您在 switch 语句块中使用 return 语句,并且您的函数是有返回值的,您还需要在 switch 之后添加相应的 return 语句以确保函数始终会返回。

  • 可选的 default 分支可以出现在任何顺序,但最好将它放在最后。它的作用类似与 if-else 语句中的 else,表示不符合任何已给出条件时,执行相关语句。

  • 您可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3。

  • 每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。( Go 语言使用快速的查找算法来测试 switch 条件与 case 分支的匹配情况,直到算法匹配到某个 case 或者进入 default 条件为止。)

  • 一旦成功地匹配到某个分支,在执行完相应代码后就会退出整个 switch 代码块,也就是说您不需要特别使用 break 语句来表示结束。

switch 语句的第二种形式是不提供任何被判断的值(实际上默认为判断是否为 true),然后在每个 case 分支中进行测试不同的条件。

switch {
    case condition1:
        ...
    case condition2:
        ...
    default:
        ...
}

switch 语句的第三种形式是包含一个初始化语句:

switch initialization {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

例如:

switch result := calculate(); {
    case result < 0:
        ...
    case result > 0:
        ...
    default:
        // 0
}

使用fallthrough可以继续指向下一个case,否则找到对应case就会退出:

package main
​
import "fmt"
​
func main() {
    k := 6
    switch k {
    case 4:
        fmt.Println("was <= 4")
        fallthrough
    case 5:
        fmt.Println("was <= 5")
        fallthrough
    case 6:
        fmt.Println("was <= 6")
        //fallthrough
    case 7:
        fmt.Println("was <= 7")
        fallthrough
    case 8:
        fmt.Println("was <= 8")
        fallthrough
    default:
        fmt.Println("default case")
    }
}

for

基于计数器的迭代

格式:

for 初始化语句; 条件语句; 修饰语句 {}

注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号, 大括号 { } 则是必须的。

例如:

func main() {
    loopFor()
}
func loopFor() {
    for i := 0; i < 100; i++ {
        fmt.Println(i)
    }
}

基于条件判断的迭代

for 结构的第二种形式是没有头部的条件判断迭代(类似其它语言中的 while 循环),基本形式为:for 条件语句 {}。(相当于while循环)

您也可以认为这是没有初始化语句和修饰语句的 for 结构,因此 ;; 便是多余的了。

package main
​
import "fmt"
​
func main() {
    var i int = 5
​
    for i >= 0 {
        i = i - 1
        fmt.Printf("The variable i is now: %d\n", i)
    }
}

for-range 结构

这是 Go 特有的一种的迭代结构,您会发现它在许多情况下都非常有用。它可以迭代任何一个集合。语法上很类似其它语言中 foreach 语句,但您依旧可以获得每次迭代所对应的索引。一般形式为:for ix, val := range coll { }val 始终为集合中对应索引的值拷贝,因此它一般只具有只读性质,对它所做的任何修改都不会影响到集合中原有的值(注:如果 val 为指针,则会产生指针的拷贝,依旧可以修改集合中的原值)。

例子:

for pos, char := range str {
...
}

break 和 continue

和java一样。

标签 与 goto

for、switch 或 select 语句都可以配合标签(label)形式的标识符使用,即某一行第一个以冒号(:)结尾的单词。(标签的名称是大小写敏感的,为了提升可读性,一般建议使用全部大写字母)

package main
​
import "fmt"
​
func main() {
​
LABEL1:
    for i := 0; i <= 5; i++ {
        for j := 0; j <= 5; j++ {
            if j == 4 {
                continue LABEL1
            }
            fmt.Printf("i is: %d, and j is: %d\n", i, j)
        }
    }
​
}

使用goto结合lable

package main
​
func main() {
    i:=0
    HERE:
        print(i)
        i++
        if i==5 {
            return
        }
        goto HERE
}

如果您必须使用 goto,应当只使用正序的标签(标签位于 goto 语句之后),但注意标签和 goto 语句之间不能出现定义新变量的语句,否则会导致编译失败。

错误示例:

// compile error goto2.go:8: goto TARGET jumps over declaration of b at goto2.go:8
package main
​
import "fmt"
​
func main() {
        a := 1
        goto TARGET // compile error
        b := 9
    TARGET:  
        b += a
        fmt.Printf("a is %v *** b is %v", a, b)
}

学习参考资料:

《Go 入门指南》 | Go 技术论坛 (learnku.com)

Go 语言之旅

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Benaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值