36.笔记go语言——函数

来源:互联网 发布:java做爬虫 编辑:程序博客网 时间:2024/05/29 18:22

36.笔记go语言——函数

函数是构建Go程序的基础部件.Go不允许函数嵌套。然而你可以利用匿名函数实现它.

作用域

在Go中,定义在函数外的变量是全局的,那些定义在函数内部的变量,对于函数来说是局部的。如果命名覆盖——一个局部变量与一个全局变量有相同的名字——在函数执行的时候,局部变量将覆盖全局变量。

代码:

package main

var a = 6

func main() {

                                        p()

                                        q()

                                        p()

}

func p() {

                                        println(a)

}

func q() {

                                        a:= 5

                                        println(a)

}

输出:

                                        6

                                        5

                                        6

多值返回

Go一个非常特别的特性(对于编译语言而言)是函数和方法可以返回多个值(Python 和 Perl 同样也可以)。这可以用于改进一大堆在 C 程序中糟糕的惯例用法:修改参数的方式,返回一个错误(例如遇到EOF则返回-1)。在Go中,Write返回一个计数值和一个错误:“是的,你写入了一些字节,但是由于设备异常,并不是全部都写入了。”

代码:

package main

func main() {

                                        a:= []byte{'1', '2', '3', '4'}

                                        varx int

                                        println(len(a))

                                        fori := 0; i < len(a); {

                                                                                x,i = nextInt(a, i)

                                                                                println(x)

                                        }

}

func nextInt(b []byte, i int) (int, int) {

                                        x:= 0

                                        //假设所有的都是数字

                                        for; i < len(b); i++ {

                                                                                x= x*10 + int(b[i]) - '0'

                                        }

                                        returnx, i

}

没有元组作为原生类型,多返回值可能是最佳的选择。你可以精确的返回希望的值,而无须重载域空间到特定的错误信号上。

命名返回值

Go函数的返回值或者结果参数可以指定一个名字,并且像原始的变量那样使用,就像输入参数那样。如果对其命名,在函数开始时,它们会用其类型的零值初始化;如果函数在不加参数的情况下执行了 return语句,结果参数的当前值会作为返回值返回。用这个特性,允许(再一次的)用较少的代码做更多的事。

名字不是强制的,但是它们可以使得代码更加健壮和清晰:这是文档。例如命名int类型的nextPos返回值,就能说明哪个代表哪个。

由于命名结果会被初始化并关联于无修饰的return,它们可以非常简单并且清晰。

延迟代码

假设有一个函数,打开文件并且对其进行若干读写。在这样的函数中,经常有提前返回的地方。如果你这样做,就需要关闭正在工作的文件描述符。

为了解决这些,Go有了defer语句。在defer后指定的函数会在函数退出前调用。

延迟的函数是按照后进先出(LIFO)的顺序执行.

函数符号也就是被叫做闭包的东西

变参

接受变参的函数是有着不定数量的参数的。为了做到这点,首先需要定义函数使其接受变参.

arg ...int告诉Go这个函数接受不定数量的参数。注意,这些参数的类型全部是int。

函数作为值

就像其他在Go中的其他东西一样,函数也是值而已。

例如代码:

package main

 

func main() {

                                        a:= func() {

                                                                                println("Hello")

                                        }

                                        a()

}

回调

当函数作为值时,就可以很容易的传递到其他函数里,然后可以作为回调。

恐慌(Panic)和恢复(Recover)

Go没有像Java那样的异常机制:不能抛出一个异常。作为替代,它使用了恐慌和恢复(panic-and-recover)机制。一定要记得,这应当作为最后的手段被使用,你的代码中应当没有,或者很少的令人恐慌的东西。这是个强大的工具,明智的使用它。

Panic

panic是一个内建函数,可以中断原有的控制流程,进入一个令人恐慌的流程中。当函数F调用panic,函数F的执行被中断,并且F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到程序崩溃时的所有goroutine返回。恐慌可以直接调用panic产生。也可以由运行时错误产生,例如访问越界的数组。

Recover

一个内建的函数,可以让进入令人恐慌的流程中的 goroutine 恢复过来。recover仅在延迟函数中有效。

对应异常机制,Go 的这种错误机制或许可以叫做恐慌机制:当你遇到它时应该感到恐慌(panic),然后应该恢复(recover)它.在正常的执行过程中,调用recover会返回nil并且没有其他任何效果。如果当前的goroutine陷入恐慌,调用recover可以捕获到panic的输入值,并且恢复正常的执行。

原创粉丝点击