Go流程语句
go语言流程语句
条件分支
写法习惯:
左大括号和if在同一行,当有 else if 结构时,前段代码块的右大括号}和 else if 关键字在同一行。
每个分支内的代码缩进 4个或 8个空格,或者1个tab,右大括号}与对应的 if 关键字垂直对齐。
条件语句两侧的括号可以被省略
if condition {
/* condition true时执行 */
}
if condition {
/* condition true时执行 */
} else {
/* condition false时执行 */
}
if 布condition1 {
/* condition1 true时执行 */
} else if condition2{
/* condition2 true时执行 */
} else{
/* 在上面条件都不满足false时,执行*/
}
习惯
当一条if语句没有进入下一条语句时,即主体以break、continue、 goto或结尾,省略 了return不必要的语句。
如果成功情况继续向下运行,代码可读性好,消除了出现的错误情况。由于错误情况往往以return 语句结尾,因此生成的代码不需要else语句。
f, err := os.Open(name)
if err != nil {
// 错误直接return,此if无需添加else语句
return err
}
// 正确时继续运行
d, err := f.Stat()
if err != nil {
f.Close()
// 错误直接return,此if无需添加else
return err
}
// 都正确,则运行
codeUsing(f, d)
循环
习惯
for的表达式可以不用括号,{ 和for关键字在同一行。
可以使用continue 和 break 来控制循环,break可以指定跳出哪个循环(break flag)。
//for表明接下来的代码是for循环结构;init是初始化语句;condition 为true时成立;post是每次循环结束后执行的语句;循环体代码块是要重复执行的代码。
for init; condition; post {
//循环体代码块
}
// 例如
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
//如果您正在循环遍历数组、切片、字符串或映射,或者从通道读取,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
}
Switch
表达式可以是常量或者整数等,case 会从上到下进行判断,直到找到匹配项
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
}
//break语句可用于提前终止switch
//有时跳出周围的循环,而不是 switch,在 Go 中,这可以通过在循环上放置一个标签并“打破”该标签来完成
Loop:
for n := 0; n < len(src); n += size {
switch {
case src[n] < sizeOne:
if validateOnly {
break
}
size = 1
update(src[n])
case src[n] < sizeTwo:
if n+1 >= len(src) {
err = errShortInput
// 跳出Loop
break Loop
}
if validateOnly {
break
}
size = 2
update(src[n] + src[n+1]<<shift)
}
}
//continue
//该continue语句也接受一个可选标签,但它仅适用于循环
// Compare returns an integer comparing the two byte slices,
// lexicographically.
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b
func Compare(a, b []byte) int {
for i := 0; i < len(a) && i < len(b); i++ {
switch {
case a[i] > b[i]:
return 1
case a[i] < b[i]:
return -1
}
}
switch {
case len(a) > len(b):
return 1
case len(a) < len(b):
return -1
}
return 0
}
Type Switch
switch 也可用于发现接口变量的动态类型。这样的类型切换type使用括号内带有关键字的类型断言的语法。如果 switch 在表达式中声明了一个变量,则该变量将在每个子句中具有相应的类型。在这种情况下重用名称也是惯用的,实际上是在每种情况下声明一个具有相同名称但类型不同的新变量
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}