Go语言基础2 | 青训营笔记

75 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
本文主要介绍Go语言中的的for,if,switch三种结构。

for循环

在Go语言中,表达循环的方式只有for,for循环有三种形式,如下所示:

// Like a C for
for init; condition; post { }

// Like a C while
for condition { }

// Like a C for(;;)
for { }

可以发现,判断条件外不需要套小括号。

若想遍历数组、切片、字符串或者映射,或从信道中读取消息, range 子句能够帮你轻松实现循环。如以下代码所示:

for key, value := range oldMap {
	newMap[key] = value
}

//如果只需要遍历第一项,去掉第二个就行了
for key := range m {
	if key.expired() {
		delete(m, key)
	}
}
//若只需要该遍历中的第二个项(值),请使用空白标识符,即下划线来丢弃第一个值:
sum := 0
for _, value := range array {
	sum += value
}

对于字符串,range 能够提供更多便利。它能通过解析 UTF-8, 将每个独立的 Unicode 码点分离出来。错误的编码将占用一个字节,并以符文 U+FFFD 来代替。

for pos, char := range "日本 \ x80 語" { // \x80 is an illegal UTF-8 encoding
	fmt.Printf("character %#U starts at byte position %d\n", char, pos)
}

//res
character U+65E5 '日' starts at byte position 0
character U+672C '本' starts at byte position 3
character U+FFFD '�' starts at byte position 6
character U+8A9E '語' starts at byte position 7

最后,Go 没有逗号操作符,而 ++ 和 -- 为语句而非表达式。 因此,若你想要在 for 中使用多个变量,应采用平行赋值的方式 (因为它会拒绝 ++ 和 --).如下图所示:

// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
	a[i], a[j] = a[j], a[i]
}

if语句

if x > 0 {
	return y
}

上述代码中,大括号是强制的

if和switch可以接受初始化语句,因此可以用他们设置局部变量,如下图所示:

if err := file.Chmod(0664); err != nil {
	log.Print(err)
	return err
}

如果有else的话,if-else的结构如下所示:

if num := 9; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "has 1 digit")
	} else {
		fmt.Println(num, "has multiple digits")
	}

上面代码中,else要和“ } ”在同一行,因为如果在“ } ”后回车后,编译器会将“}”之后的回车替换为“ ”,那么就是两个语句了。

switch语句

基本语法

switch condition {
			case A:
					...
			case B:
					...
			default:
					...

上述代码中,condition,default可有可无,并且default也不是强制在最下边,它可以放在case A,case B的上方,对最终结果没有影响。

func unhex(c byte) byte {
	switch {
	case '0' <= c && c <= '9':
		return c - '0'
	case 'a' <= c && c <= 'f':
		return c - 'a' + 10
	case 'A' <= c && c <= 'F':
		return c - 'A' + 10
	}
	return 0
}
a := 2
	switch a {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	case 4, 5:
		fmt.Println("four or five")
	default:
		fmt.Println("other")
	}

此外,switch…case…还可以用于类型选择,如下面代码所示:

var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
	fmt.Printf("unexpected type %T", t)       // %T 输出 t 是什么类型
case bool:
	fmt.Printf("boolean %t\n", t)             // t 是 bool 类型
case int:
	fmt.Printf("integer %d\n", t)             // t 是 int 类型
case *bool:
	fmt.Printf("pointer to boolean %t\n", *t) // t 是 *bool 类型
case *int:
	fmt.Printf("pointer to integer %d\n", *t) // t 是 *int 类型
}