GO语言学习笔记(三)流控制、函数

流控制

golang精简了控制语句,但足够我们使用。

if...else 语句需要注意一点的是对初始化语句的支持。

	if x := xtest(); x == 0 {  // 先执行xtest函数,再对x==0条件表示式判断布尔值
		fmt.Println(x)
	}

switch...case语句同样对初始化语句支持,此外不能出现重复的cacs值,单个case支持多条件匹配。

package main

import "fmt"

func xtest(x int) {
	switch y := x + 1; y {
	case 1, 2, 3: // 当x满足其中一项时即匹配
		fmt.Println("1|2|3")
	case 4:
		fmt.Println("4")
	case 5: // 该语句等同于case5 : break
	default:
		fmt.Println("Unkown")
	}
}

func main() {
	xtest(2)
	xtest(3)
	xtest(4)
}

switch可以省略条件表达式,默认为true。

package main

import "fmt"

func xtest(x int) {
	switch {  // 等同于 switch true
	case x > 0:
		fmt.Println("Positive", x)
	case x < 0:
		fmt.Println("Nagetive", x)
	default:
		fmt.Println("Zero", x)
	}
}

func main() {
	xtest(0)
	xtest(1)
	xtest(-1)
}

需要注意的是switch的条件表达式如果未false时,case匹配规则刚好相反,为不满足case的条件表达式时匹配。

package main

import "fmt"

func xtest(x int) {
	switch false {
	case x >= 0:
		fmt.Println("Positive", x)
	case x <= 0:
		fmt.Println("Nagetive", x)
	default:
		fmt.Println("Zero", x)
	}
}

func main() {
	xtest(0)
	xtest(1)
	xtest(-1)
}

switch..case语句无需显示执行break语句,case执行完毕后自动跳出,如果需要继续执行下一个的case,可使用fallthrough,但不再匹配后续case条件表达式。fallthrough必须放在case块结尾.。

package main

import "fmt"

func xtest(x int) {
	switch {
	case x > 0:
		fmt.Println("Positive", x)
		fallthrough
	case x < 0:
		fmt.Println("Nagetive", x)
		fallthrough
	default:
		fmt.Println("Zero", x)
	}
}

func main() {
	xtest(3)
}

golang中循环语句只有for一种,但是for的条件表达式有多种形式。

package main

import "fmt"

func main() {

	for i := 0; i < 2; i++ { // 常用方式
		fmt.Println("i=", i)
	}

	j := 0
	for j < 2 { // 相当于 for _; j< 2; _
		fmt.Println("j=", j)
		j++
	}

	for { // 相当于for true
		break
	}

	i := []string{"hello", "world"}
	for k, s := range i { // 遍历s切片,k可以替换成_
		fmt.Println(k, s)
	}

}

函数

golang函数使用func定义函数,需要注意几点特性

1)函数无需前置声明

2)函数不支持嵌套定义

3)函数不支持重载

4)函数支持不定参数

5)函数支持多返回值

6)函数支持命名返回值

7)函数支持匿名函数和闭包

函数定义包括函数名、参数列表、返回值列表(可省略)和函数体。

func name(parameter list)(rusult list){
    body
}

函数在golang中作为第一对象,可以作为参数、返回值、变量。相同返回值列表和参数列表的函数被认作一种数据类型。

package main

import "fmt"

type priInt func(int) int

func a(x int) int {
	fmt.Println("Func a", x)
	x++
	return x
}

func b(x int) int {
	fmt.Println("Func b", x)
	return x
}

func test(x priInt) priInt {
	x(1)
	return x
}

func main() {
	var funtest priInt
	funtest = test(a)
	funtest(2)
	funtest = test(b)
	funtest(2)
}

golang函数的参数列表支持相邻同类型合并,golang函数参数列表支持不定长参数,本质上不定长参数是切片。切片必须放在参数列表尾部。

package main

import "fmt"

func test(x, y int, a ...string) {
	fmt.Println(x, y, a)
}

func main() {
	test(1, 2, "hello", "abc")
}

golang函数支持多返回值,并且函数支持命名返回值,即返回值变量作为局部变量使用方式和参数一致。

package main

import "fmt"

func test1() (int, int, int) { // 多返回值函
	return 1, 2, 3
}

func test2() (x int, y string) {
	x = 1
	y = "hello"
	return // 隐式转化 相当于 return x, y
}

func main() {
	a, b, _ := test1() // 多余不需要的返回值可使用_替换
	fmt.Println(a, b)

	c, d := test2()
	fmt.Println(c, d)
}

golang函数支持匿名函数,与正常函数相比,减去了函数名称。匿名函数常用在函数内部嵌套上,匿名函数可以赋值给变量,或者作为参数、返回值。

package main

import "fmt"

func test(a func(int)) func(string) { // 匿名函数作为参数和返回值
	a(1)
	return func(str string) {
		fmt.Println(str)
	}
}

func main() {
	func() {
		fmt.Println("hello")
	}() //声明匿名函数并直接调用

	a := func() {
		fmt.Println("world")
	} //声明匿名函数并赋值给变量
	a()
	b := test(func(i int) {
		fmt.Println("abc")
	})

	b("123")
}

Golang函数支持闭包特性,闭包指的是函数在使用中引用了函数上下文的环境。闭包会使上下文环境声明周期变长,如果上下文中定义了局部变量,该变量将被分配到堆中。

package main

import "fmt"

func test() func() {
	x := 1
	fmt.Println(x, &x)
	return func() {
		fmt.Println(x, &x) // 匿名函数引用了上下文变量x
	}
}

func main() {
	a := test()
	a()
}

golang函数支持延时调用,当函数运行流程结束后,开始执行延时调用函数。使用defer可以向当前函数注册演示调用函数,当函数注册了多个延时调用函数,其执行顺寻是后注册的先执行。

package main

import "fmt"

func test() int { 
	x := 1
	defer func() {
		x++
		fmt.Println("defer", x)
	}()

	defer func() {
		x++
		fmt.Println("defer2", x) // 先执行
	}()

	return x // 执行完后开始执行延时调用
}

func main() {
	fmt.Println(test())
}

golang函数使用painc和recover实现类似try...catch的结构化异常捕捉。painc会立即终止当前函数流程,并执行当前函数延迟调用函数。

在延时调用函数中使用recover捕捉painc提交的错误对象。需要注意的是golang程序异常时,使用painc代表着程序终止。

package main

import (
	"fmt"
	"log"
)

func main() {
	defer func() {
		if err := recover(); err != nil { // 捕捉异常
			log.Fatalln(err)
		}
	}()

	panic("This is painc") // 终止函数流程

	fmt.Println("main") // 不会执行
}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值