Go语言函数Function
Go函数不支持嵌套、重载和默认参数
但支持以下特性:
无需声明原型、不定长度参数、多返回值、命名返回值参数、匿名函数、闭包
定义函数使用关键字func,且左大括号不能另起一行
函数也可以作为一种类型使用
不定参数
不定参数的传递:
任意类型的不定参数:
如果你希望传任意类型的不定参数,可以指定类型为interface{},下面是Go语言标准库中fmt.Printf()的函数原型:
func Printf(format string, args ...interface{}){
//...
}
用interface{}传递任意类型数据是Go语言的管理用法。使用interface{}仍然是类型安全的。
defer
defer的执行方式类似其他语言的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个调用
即使函数发生严重错误也会执行
支持匿名函数的调用
常用于资源清理,文件关闭,解锁以及记录时间等操作
通过与匿名函数配合可以在return之后修改函数计算结果
如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则则是引用某个变量的地址
Go没有异常机制,但有panic/recover模式来处理错误
Panic可以在任何地方引发,但recover只有在defer调用的函数中有效
函数定义
Go语言函数定义格式如下:
func function_name( [parameter list] ) [return_types] {
函数体
}
函数定义解析:
func:函数由func开始声明
function_name:函数名称,函数名称和参数列表一起构成了函数签名;
parameter list:参数列表,参数就像一个占位符,当函数被调用时,可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是函数也可以不包含参数。
return_types:返回类型,函数返回以列值。return_types是该列值的数据类型。有些功能不需要返回值,这种情况下reutrn_types不是必须的;
函数体:函数定义的代码集合
函数调用
当创建函数时,定义了函数需要做什么,通过调用该函数执行指定任务。
调用函数,向函数传递参数,并返回值。
函数返回多个值
Go函数可以返回多个值。
函数参数
函数如果使用参数,该变量可称为函数的形参
形参就像定义在函数体内的局部变量
调用函数,可以通过两种方式来传递参数:
函数用法
函数作为值:
Go 语言可以很灵活的创建函数,并作为值使用。以下实例中我们在定义的函数中初始化一个变量,该函数仅仅是为了使用内置函数 math.sqrt() ,实例为:
package main
import (
"fmt"
"math"
)
func main(){
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 使用函数 */
fmt.Println(getSquareRoot(9))
}
闭包
Go 语言支持匿名函数,可作为闭包。匿名函数是一个”内联”语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:
package main
import "fmt"
func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
}
func main(){
/* nextNumber 为一个函数,函数 i 为 0 */
nextNumber := getSequence()
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())
/* 创建新的函数 nextNumber1,并查看结果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}
方法:
Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。语法格式如下:
func (variable_name variable_data_type) function_name() [return_type]{
/* 函数体*/
}
下面定义一个结构体类型和该类型的一个方法:
package main
import (
"fmt"
)
/* 定义函数 */
type Circle struct {
radius float64
}
func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("Area of Circle(c1) = ", c1.getArea())
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
//c.radius 即为 Circle 类型对象中的属性
return 3.14 * c.radius * c.radius
}