GO入门——5. 函数

1 函数

  • Go 函数 不支持 嵌套、重载和默认参数

  • 定义函数使用关键字 func,且左大括号不能另起一行

  • 函数也可以作为一种类型使用

  • 无需声明原型

  • 不定长度变参

func A(a string,c ... int){
//不定长变参必须在最后
//此时c为一个slice
}
  • 多返回值
func A() (int,int){
//返回多个int
}
  • 命名返回值参数
func A() (a int,b string){
//此时a,b已经声明,直接给其赋值不需要return
//也可以不管a,b,直接return别的
}
  • 匿名函数
func A(){
a:=func (){
fmt.Println("匿名函数")
}
a()
}
  • 闭包
func main() {
s := []int{0, 1, 2}
c := closure(s)
fmt.Println(c()) //输出0
s[0] = 10
fmt.Println(c()) //输出10
}
func closure(s []int) func() int {
return func() int {
return s[0] //该s是传入slice的地址,因此后续使用将一直使用传入的slice
}
}

2 defer

  • 执行方式类似其它语言中的析构函数,在函数体执行结束后

    按照调用顺序的相反顺序逐个执行
  • 即使函数发生严重错误也会执行
  • 支持匿名函数的调用
  • 常用于资源清理、文件关闭、解锁以及记录时间等操作
  • 通过与匿名函数配合可在return之后修改函数计算结果
  • 如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer

    时即已经获得了拷贝,否则则是引用某个变量的地址
/*输出顺序如下
j= 13
j= 13
j= 13
i= 2
i= 1
i= 0
*/
func funcDefer() {
for i := 0; i < 3; i++ {
defer fmt.Println("i=", i) //defer按照栈顺序出入
}
for j := 10; j < 13; j++ {
defer func() {
fmt.Println("j=", j) //传入闭包的j为地址,执行完函数后j=13,所以后续均为13
}() //后面的括号表示调用这个匿名函数
}
}
  • Go 没有异常机制,但有 panic/recover 模式来处理错误
  • Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效
/*如果不使用recover()将输出
A
B
panic: B err
*/
/*使用recover()将输出
A
B
recover in B
C
*/
func pc() {
A := func() {
fmt.Println("A")
} B := func() {
fmt.Println("B")
defer func() {
//recover相当于catch了异常,异常存入了err
if err := recover(); err != nil {
fmt.Println("recover in B")
}
}()
panic("B err") //相当于抛出异常
}
C := func() {
fmt.Println("C")
} A()
B()
C() }
上一篇:Material Designer的低版本兼容实现(十三)—— ProgressBar


下一篇:转载Entity Framework 5.0(EF first)中的添加,删除,修改,查询,状态跟踪操作