go函数的特点
go的函数可以有多个返回值
对于常用java开发的来说,有没有觉得实体类很恶心。
对于有经验的java开发,一定会觉得很恶心,当我们需要优化代码时,会发现入参有一大堆,返回值也有一大堆,就不得不新建一个class作为实体类,就存返回值。
实体类越来越多,代码特别难看,强迫症要犯了。
而golang可以返回多个值,解决了这个问题,缩短了开发周期。
go的返回值也要取个变量名(规范)
当然也可以不写,但是我们代码不止要写,而且一定要写的漂亮,像框架一样,也的很优雅,规范一些
函数的基本写法
func [函数名] ( [函数入参] )( [函数返回值] ){
函数体
}
来看一些示例
有入参无返回值的
a:=10
func firstFunction(a int)(){
//函数体
}
func firstFunction(a,b int)(){
//函数体
}
func firstFunction(a int,b string)(){
//函数体
}
不定参数
记的java中mybatis源码常用的可变参数吗,用…来表示
go也是一样,语法如下:
[变量名]…[type],如: a…int,b…string
func ChangeParamter(args...string){
//函数体
}
不定参数也可以多个传递
记得调用的时候要入参哦
func ChangeParamter(a string,args...int){
//函数体
}
func main(){
ChangeParamter("qwe",1,3,4,5)
}
不定参数只能放在最后的一个
来个错误示范
func ChangeParamter(a...string,args...int){
//我是错误示范
}
不定参数在函数间传递(一下子全部传过去)
用变量名加…,获取所有参数
[变量名]…
func ChangedParamter1(args...int){
//函数体
}
func ChangedParamter2(args...int){
ChangedParamter1(args...)
}
不定参数在函数间传递(传指定位置的值)
把可变参数0到2位置的值传过去
func ChangedParamter1(args...int){
//函数体
}
func ChangedParamter2(args...int){
ChangedParamter1(args[:2]...)
}
把可变参数2后面的值传过去
func ChangedParamter1(args...int){
//函数体
}
func ChangedParamter2(args...int){
ChangedParamter1(args[2:]...)
}
下面开始写一些有返回值的
先来一个不规范的
func function()(result int){
return 666
}
再来一个规范的,也是官方要求的
func function()(result int){
result = 666
return
}
多返回值
func function()(result int,str string,b int){
result,str,b = 666,"123",3
return
}
用return可以直接返回(跟其他语言一样)
func function(){
//直接会return掉,退出函数
return
}
给函数取别名!type
函数也是一种数据类型!
这很重要,这也算多态,是go的新写法,很灵活
想要代码写的漂亮,这要熟练掌握
这个SpecialName声明后就变成了一个函数的类型
在main方法里面进行调用
//声明一个函数类型
type SpecialName func(a int)(b int )
func function(a int)(b int ){
b=a
return
}
func main(){
//声明一个SpecialName函数类型的变量
var testfunc SpecialName;
//既然testfunc是一个变量,那一定可以赋值
//把function方法赋值给SpecialName类型
testfunc=function
//用多态的方式调用function
testfunc(1,3)
}
接下来将用函数实现多态
用一个方法实现加减乘除
这里开始难了,这个功能很像java的接口和实现接口,策略模式!
package main
//加法
func Add(a int,b int)(result int){
result=a+b
return
}
//减法
func Sub(a int,b int)(result int){
result=a+b
return
}
//乘法
func Mult(a int,b int)(result int){
result=a+b
return
}
//除法
func Div(a int,b int)(result int){
result=a+b
return
}
//声明一个叫做math的函数类型
type Math func(a int,b int)(result int)
//计算总方法
//入参为Math
func Caculate(a int,b int,method Math)(result int){
//实现根据入参输入的类型,做运算,实现多态
result=method(a,b)
return
}
func main() {
//调用加法
Caculate(1,2,Add)
//调用减法
Caculate(1,2,Sub)
//调用乘法
Caculate(1,2,Mult)
//调用除法
Caculate(1,2,Div)
}
匿名函数和闭包
匿名函数也就是没有函数名字
闭包就是该函数可以拿到外面的值,拿到全局变量的值
有点像java,匿名内部类的意思
func main(){
//定义一个匿名函数并赋值个体变量f1
f1:=func(){
//函数体
}
//定义一个匿名函数并直接调用
func(){
//函数体
}()
}
有参数有返回值的匿名函数直接调用
func main(){
//e,f拿到函数返回值
e,f:=func(a int,b int)(c int ,d int){
//函数体
return c,d
}(10,10)
}
函数的返回值也可以是一个匿名函数
//写法一
func Test1() func(){
f:=func(){
//函数体
}
return f
}
//写法二
func Test2() func(){
return func(){
//函数体
}
}
延迟调用defer
defer只能放在函数的内部
在函数结束之前的一刹那执行
比如,读文件时关闭流
defer就像是java中的finally,无论怎样都会执行
func main(){
defer printf("a")
printf("b")
//最终会输出ba
}
多个defer语句会按照先进后出的顺序执行,就是反者执行
func main(){
defer printf("a")
defer printf("b")
//最终会输出ba
}
局部和全局变量可以重名,使用时就近原则
package main
a:=10
func main{
var a float32
}