欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

go流程控制

程序员文章站 2022-06-24 20:01:29
...
—————— 
go仅有三种流程控制语句:if、switch、for

—————— if
func main() {
	x := 100
	if x > 0 {
		println("x")
	} else if x < 0 {
		println("-x")
	} else {
		println("0")
	}
}

支持执行初始化函数或定义块局部变量
func main() {
	x := 10
	if xinit(); x == 0 { #优先执行xinit函数
		println("a")
	}

	if a, b := x+1, x+10; a < b { #定义一个或多个局部变量(或函数返回值)
		println(a)
	} else {
		println(b)
	}
}

减少代码块嵌套,并重构为函数
import (
	"errors"
	"log"
	"strconv"
)

func check(s string) error {
	n, err := strconv.ParseInt(s 10, 64)
	if err != nil || n < 0 || n > 10 || n%2 != 0 {
		return errors.New("invalid number")
	}

	return nil
}

func main() {
	s := 10

	if err := check(s); err != nil {
		log.Fatalln(err)
	}

	println("ok")
}

—————— switch
func main() {
	x:=100

	switch {
		case x > 0:
			println("x")
		case x < 0:
			println("-x")
		default:
			println("0")
	}
}

func main() {
	a, b, c, x := 1, 2, 3, 2

	switch  x {
		case a, b:           #OR关系
			println("a | b")
		case x > 3 && x <=5:
			println("a | b")
		case c:
			println("c")
		case 4:              #常量
			println("d")
		default:
			println("z")
	}
}
输出
a | b

—————— for
for i := 0; i < 3; i++ {
	println(i)
}

for x < 5 { #等同于  while (x < 5) {}
	x++
}

for { #相当于 while true {} 或 for true {}
	break
}

初始化语句仅执行一次
func main() int {
	print("count.")
	return 3
}

func main() {
	for i, c := 0, count(); i < c; i++ { #初始化语句的count函数仅执行一次
		println("a", i)
	}

	c := 0
	for c < count() { #条件表达式中的count函数重复执行
		println("b", c)
		c++
	}
}
输出
count.a 0
a 1
a 2

count.b 0
count.b 1
count.b 2
规避方式在初始化表达式中定义局部变量保存count结果

for...range迭代遍历,支持字符串、数组、数组指针、切片、字典、通道类型,返回索引、键值
func main() {
	data := []int{100, 101, 102}

	for i, n := range data {
		println(i, ":", n)
	}
}
输出:
0 : 100
1 : 101
2 : 102

允许返回单值,用“_”忽略
func main() {
	data := [3]string{"a", "b", "c"}

	for i := range data { #只返回1st value
		println(i, data[i])
	}

	for _, s := range data { #忽略1st value
		println(s)
	}

	for range data { #仅迭代,不返回。可用来执行清空channel操作

	}
}
for循环、range迭代,其定义的局部变量会重复使用

range会复制目标数据,受直接影响的是数组,可改变数组指针或切片类型
func main() {
	data := [3]int{10, 20, 30}

	for i, x :=range data { #从data复制品中取值
		if i == 0 {
			data[0] += 100
			data[1] += 200
			data[2] += 300
		}

		fmt.Printf("x: %d, data: %d\n", x, data[i])
	}

	for i, x :=range data[:] { #仅复制slice,不包括底层array
		if i == 0 {
			data[0] += 100
			data[1] += 200
			data[2] += 300
		}

		fmt.Printf("x: %d, data: %d\n", x, data[i])
	}
}
输出
x: 10, data: 110
x: 20, data: 220 #range返回的依旧是复制值
x: 30, data: 330

x: 110, data: 210 #当i == 0 修改data时,x已经取值,所以时110
x: 420, data: 420 #复制的仅是slice自身,底层array依旧是原对象
x: 630, data: 630

range目标表达式是函数调用,仅被执行一次
func main() []int {
	println("origin data.")
	return []int{10, 20, 30}
}

func main() {
	for i,x := range data() {
		println(i, x)
	}
}
输出
origin data.
0 10
1 20
2 30

——————