函数function
-Go函数不支持嵌套、重载、和默认参数
-支持以下特性:
-无需声明原型、不定长度变参、多返回值、命名返回值参数、匿名函数、闭包
-定义函数使用关键字func,且最左括号不能另起一行
-函数也可以作为一种类型使用
#func 函数名(参数列表,可为空)(设置可返回值类型,作为可选部分){}
func A1(a int,b string)(int,string){} //定义返回的类型
func A2(a ,b,c int)(int,string){} //定义函数值都为int类型
func A3(a int,b string)(int,string){}
##有命名返回值和不命名返回值区别:
定义多个参数:可用不定常变参
func main(){
A(1,2,3,4,5,6)
}
func A(a...int){
fmt.Println(a)
}
值类型传递和SLICE传递区别:
##函数调用:
package main
import "fmt"
func max(num1 int, num2 int) int {
var result int
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
func main() {
var a int = 100
var b int = 200
var ret int
ret = max(a, b)
fmt.Printf("最大值是:%d\n", ret)
}
函数定义时指出,函数定义时有参数,该变量可称为函数的形参。形参就像定义在函数体内的局部变量。
但当调用函数,传递过来的变量就是函数的实参,函数可以通过两种方式来传递参数:
值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
2. 引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数
不定参数类型:
func myfunc(args ...int){}
egg:
package main
import "fmt"
func main() {
//var a int = 100
//var b int = 200
myfunc(100, 200, 300, 400, 500)
}
func myfunc(args ...int) {
fmt.Println(args)
for _, arg := range args {
fmt.Println(arg)
}
}
匿名函数:
在Go里面,函数可以像普通变量一样被传递或使用,Go语言支持随时在代码里定义匿名函数,匿名函数由一个不带函数名的函数声明和函数体组成。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
func main(){
a :=func(){ //函数里没有名字
fmt.Println("FUNC A")
}
a()
}
func A(){
fmt.Println("FUNC A")
}
闭包:闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)
func main(){
a :=clousre(10){
fmt.Println(func(1))
fmt.Println(func(2))
}
}
func clousre(x int)func(int)int{
return func(y int)int{
return x+y
}
fmt.Println("FUNC A")
}
defer:(调用:先进后出,后进先出原则)
-执行方式类似其他语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行
-即使函数发生严重错误也会执行
-支持匿名函数的调用
-常用于资源清理、文件关闭、锁解以及记录时间等操作
-通过与匿名函数配合可在return之后修改函数计算结果
-如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即以获得了拷贝,否则则是引用某个变量的地址
-Go没有异常机制,但有panic/recover模式来处理错误
-Panic可以在任何地方引发,但recover只有在defer调用的函数中有效
func main(){
for i :=0;i<3;i++{
defer fmt.Println(i)
}
}
func main(){
for i :=0;i<3;i++{
defer func(){
fmt.Println(i)}()
}
}
##recover案例
package main
import "fmt"
func main() {
A()
B()
C()
}
func A() {
fmt.Println("func A")
}
func B() {
defer func() {
if err := recover(); err != nil {
fmt.Println("Recover in B")
}
}()
panic("func B") //如果只有这条,执行到这就停止了
}
func C() {
fmt.Println("func C")
}