Go语言里的函数可分为两种:
带名字的叫普通函数
没带名字的叫匿名函数
函数的申明
使用func
关键字,后面一次接函数名
,参数列表
,返回值列表
,用{}包裹的代码块
func函数名(形式参数列表)(返回值列表){函数体}
函数的可变参数
多个类型一致的参数
//使用...类型,表示一个元素为int类型的切片funcTestParams(args...string){fmt.Printf("args:%v\n",args)}funcmain(){type_func.TestParams("A","B","C")type_func.TestParams("A","B","C","D")//args:[ABC]//args:[ABCD]}
...
是 Go 语言为了方便程序员写代码而实现的语法糖,如果该函数下有多个类型的参数,这个语法糖必须得是最后一个参数。
这个语法糖,只能在定义函数时使用。
多个类型不一致的参数
上面的例子中,我们的参数类型都为string,如果你希望多个参数切这些参数的类型都不一样,可以指定类型...interface{}
,然后再遍历。
下面代码使用之前说过的switch
和arg.(type)
来演示不一致参数的情况。
funcmain(){varv1int=1varv2int64=234varv3string="hello"varv4float32=1.234PrintType(v1,v2,v3,v4)}funcPrintType(args...interface{}){for_,arg:=rangeargs{switcharg.(type){caseint:fmt.Println(arg,"isanintvalue.")casestring:fmt.Println(arg,"isastringvalue.")caseint64:fmt.Println(arg,"isanint64value.")default:fmt.Println(arg,"isanunknowntype.")}}}
函数传递可变参数
上面提到了可以使用 ...
来接收多个参数,除此之外,它还有一个用法,就是用来解序列,将函数的可变参数(一个切片)一个一个取出来,传递给另一个可变参数的函数,而不是传递可变参数变量本身。
这个方法,只能再给函数传递参数的时候使用,这两个是成对出现的。
funcmain(){args:=[]int{1,2,3,4}test(args...)}functest(args...int){fmt.Printf("args:%v\n",args)}
函数的返回值
函数的返回值是在定义函数的时候就已经确定好了。
一般有两种情况,一种是没有返回值,一种是有。同事Go语言支持返回多个值。
当函数没有指定返回值时。函数体可以使用
return
来结束函数的运行,但return
后不能跟任何东西。
Go返回多个值的函数:
funcmain(){args:=[]int{1,2,3,4}test(args...)number1,number2,string1:=returnTwo()fmt.Printf("number1:%v\n",number1)fmt.Printf("number2:%v\n",number2)fmt.Printf("string1:%v\n",string1)}funcreturnTwo()(int,int,string){return1,2,"111"}//结果number1:1number2:2string1:111
匿名函数
匿名函数,就是没有名字的函数,它只有函数逻辑体。
下面就是一个立即执行的函数。
立即执行函数
func(dataint){fmt.Println("hello",data)}(100)
作为回调函数使用
funcmain(){excute(func(strstring){print("callback"+str)})}funcexcute(callfunc(string)){call("123")}//结果callback123
这些东西其实在其他语言里也有同样的概念,想JS
里面的匿名函数
函数作为变量
在Go里面函数,也有和JS一样的用法和概念,比如将函数赋值给变量,临时性死区等。
下面是将函数赋值给变量的方式。
funcmain(){//func1()//不删除会形成临时死区varfunc1=func(){print("success!!!!")}func1()}//结果success!!!!
然后换种方式
funcmain(){func1()//不删除会形成临时死区varfunc1=func(){print("success!!!!")}}
执行时会报错.\main.go:20:2: undefined: func1
。原因是将匿名函数赋值给变量之后,在定义func1
前的代码是找不到这个变量的.
函数和方法
在看其他代码的时候有时候会出现像这样定义函数:
funcmain(){person1:=Person{"myname"}person1.printName()}//定义一个名为Person的结构体typePersonstruct{namestring}//定义一个与Person绑定的方法func(pPerson)printName(){fmt.Print(p.name)}//gorunmain.go后的结果myname
像这种定义函数的其实是Go里面的方法,给结构体定义方法。通过函数名称前的(p Person)
,与结构体进行绑定。
方法,是一种特殊的函数。当你一个函数和对象/结构体进行绑定的时候,我们就称这个函数是一个方法。