A tour of Go (2) - Go语言运算符&流程控制

Thursday, December 17, 2020

A tour of Go (2) - Go语言运算符&流程控制

1. Go语言运算符

不需要导入包

  • 算数运算符:+, -, *, /, %, ++, --
  • 关系运算符:==, !=, >, <, >=, <=
  • 逻辑运算符:&&, ||, !
  • 位运算符:& 相与, | 相或, ^ 异或, << 左移n位(乘以2的n次方), >> 右移n位
  • 赋值运算符:=, +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=
  • 其他运算符& 返回变量存储地址, * 指针变量
func main() {
   var a int = 4
   var ptr *int	// 声明指针变量
   ptr = &a	// 将变量地址赋值给指针变量
   println("a的值为", a);    // 4
   println("*ptr为", *ptr);  // 4,*指针变量 -> 取得地址对应的变量值 
   println("ptr为", ptr);    // 824633794744 直接取得变量存储地址
}

2. 流程控制语句 —— for 循环

Go 只有一种循环结构:for 循环。

基本的 for 循环由三部分组成,它们用分号隔开:

  • 初始化语句:在第一次迭代前执行 e.g., i := 0
  • 条件表达式:在每次迭代前求值 e.g., i < 10
  • 后置语句:在每次迭代的结尾执行 e.g., i++
for i := 0; i < 10; i++ {
    sum += i
}

初始化语句通常为一句短变量声明,该变量声明仅在 for 语句的作用域中可见

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

初始化语句和后置语句是可选的,而条件表达式必须声明。

sum := 1
for ; sum < 1000; {
    sum += sum
}

此时你可以去掉分号,因为 C 的 while 在 Go 中叫做 for

sum := 1
for sum < 1000 { // 此时等价于C语言中的while
    sum += sum
}

如果省略循环条件,就会变成无限循环

3. 流程控制语句 —— if 条件

Go 的 if 语句与 for 循环类似,表达式外无需小括号 ( ) ,而大括号 { } 则是必须的。

if x < 0 {
    return x
}

for 一样, if 语句可以在条件表达式前执行一个简单的语句。

该语句声明的变量作用域仅在 if 之内。

if v := math.Pow(x, n); v < lim { // 可以在条件表示前执行一个语句,如变量短赋值
		return v
	}

if 的简短语句中声明的变量同样可以在任何对应的 else 块中使用。

4. 流程控制语句 —— switch 条件

switch 是编写一连串 if - else 语句的简便方法。它会执行第一个值等于条件表达式case 语句。

Go 只运行选定的 case,而非之后所有的 case。 实际上,Go 自动提供了在这些语言中每个 case 后面所需的 break 语句。

如果执行的 case 带有 fallthrough,程序会继续执行下一条 case,且它不会去判断下一个 case 的表达式是否为 true。直到遇见不带 fallthroughcase 或执行完全部 casedefault,程序停止。

Go 的另一点重要的不同在于 switchcase 无需为常量,且取值不必为整数

没有条件的 switchswitch true 一样。这种形式能将一长串的 if-then-else 写得更加清晰

t := time.Now() // 将不同的判断条件写在 case 条件处,代替一长串的 if-then-else
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}

5. 流程控制语句 —— defer 推迟执行

defer 语句会将函数推迟到外层函数返回之后执行。

推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用

func main() {
	defer fmt.Println("world")
	fmt.Println("hello")
}

推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

func main() { // 结果:counting, done, 9, 8, ..., 0
	fmt.Println("counting")
	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("done")
}
posted @ 2020-12-17 12:07  夜魔残月  阅读(107)  评论(0)    收藏  举报