1.函数类型

在GO语言中还有另外一种定义使用函数的方式,就是函数类型,所谓的函数类型就是将函数作为一种类型可以用来定义变量,这种用法类似于前面我们讲过的int ,float64,string等类型,这些类型都是可以用来定义变量。基本语法如下:

package main

import "fmt"

func Test(a,b int)(sum int){
   sum=a+b
   return
}

type FuncType func(a, b int) int

func main() {
   var result FuncType
   result=Test
   b:=result(3,5)
   fmt.Println(b)

说明如下:type关键字后面跟着类型的名字(FunType),FunType就是一个类型.那么FunType是一个什么类型呢?
是一个函数类型,因为FunType后面跟着func(用来定义函数的),但是这里注意的是没有函数名字。那么FunType是怎样的一个函数类型呢?是一个需要传递两个整型参数,有一个整型返回值的函数类型。

既然函数类型类似于我们前面学习过的 int ,string 等类型,那么函数类型可以用来定义变量。
var result FuncType //表示定义了一个变量叫result,该变量的 类型是FuncType类型,而该类型是一个函数类型。
下面我们可以使用result这个函数类型的变量来调用函数了。
result=Test //将要调用的函数的名字赋值给result变量(也可以理解成将result变量指向了要调用的函数),这里要注意的是:第一:Test后面不能加括号。第二:函数类型变量result要和将要调用的函数Test保持一致,所谓一致就是我们定义的函数类型FuncType的变量result,只能调用参数是两个整型的,并且有一个返回值,而且也是整型的函数。那么Test函数完全满足要求。

现在已经完成了函数类型变量result指向了函数Test,那么我们可以使用函数类型的变量result调用函数:
result(3,5)//完成函数的调用。

1.2函数作用域

1.2.1局部变量、全局变量

package main

import "fmt"

func test(){
   a:=5
   a+=1
}
func main(){
   a:=9
   test()
   fmt.Println(a)
}

输出结果是9,为什么呢?
在执行fmt.Println(a)语句之前,我们已经调用了函数Test(),并在该函数中我们已经重新给变量a赋值了。但是为什么结果没有发生变化呢?这就是变量的作用范围(作用域)的问题。在Test( )函数中定义的变量a,它的作用范围只在改函数中有效,当Test( )函数执行完成后,在该函数中定义的变量也就无效了。也就是说,当Test( )函数执行完以后,定义在改函数中所有的变量,所占有的内存空间都会被回收。所以,我们把定义在函数内部的变量称为局部变量。
局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用。并且,通过上面的案例我们发现:不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响。例如:我们在main( )函数中定义变量a,在Test( )函数中也定义了变量a,但是两者之间互不影响,就是因为它们属于不同的函数,作用范围不一样,在内存中是两个存储区域。

接下来让我们看另一种

package main

import "fmt"
var a int
func test(){
   a=5
   a+=1
}
func main(){
   a=9
   test()
   fmt.Println(a)
}

输出结果是6,我们在函数外面定义了变量a,那么该变量就是全局变量,并且Test( )函数和main( )函数都可以使用该变量。该程序的执行流程是:先执行main( )函数,给变量a赋值为9,紧接着调用Test( )函数,在改函数中完成对变量a的修改。
由于main( )函数与Test( )函数所使用的变量a是同一个,所以当Test( )函数执行完成后,变量的a已经变成了6. 回到main( )函数执行后面的代码,也就是 fmt.Println(a),输出的值就是6。所谓的全局变量:既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量.也就是定义在函数外部的变量就是全局变量。全局变量在任何的地方都可以使用。