文章目录
前言
函数在数学中为两集合间的一种对应关系:输入值集合中的每项元素都能对应唯一一项输出值集合中的元素
在编程语言中函数为一类操作的集合体,具有一定的功能,有函数名、输入(参数)、输出(返回值)
一、什么是Go语言函数?
Go语言中支持多参数、多返回值
1.Go语言函数都包含什么?
函数声明
func 函数名 (函数参数列表)(返回值类型){ 函数体 }
函数参数
值传递 引用传递 函数可以作为另一个函数的实参进行回调
函数闭包(用于函数式编程,匿名函数)
go编译器会对其进行识别,将闭包的变量存放在堆空间内 并且闭包时不是返回了一个匿名函数,而是返回了一个结构体 记录下函数返回地址和引用的环境中的变量地址 同一个函数进行闭包,会因为环境变量的不同无法共享变量 闭包函数内的变量进行改变会影响到当前所处的环境中的变量
函数方法
函数方法要接收者函数,接收者函数可以是命名类型或者结构体类型的一个值或者一个指针。 定义格式如下: 接收者区域 func(名称 类型)函数名()返回值类型{ 函数体 } 注意点: 函数方法在执行时如果接收者是一个结构体,在函数内修改结构体数据,原结构体不会修改 (会将结构体变量数据拷贝一份给和函数) 如果是一个结构体指针,那么可以生效(直接将该结构体给函数)
2.简单的实现一个函数
代码如下(示例):
// 选最大值函数 //函数名 func maxs(a, b int) int {//括号内是参数列表,括号外int是返回值类型 if a > b { return a } else { return b } }
3.实现函数多参数
这里是在编写日志系统的时候写的一个输出日志的函数
代码如下(示例):
// 日志对象的方法,用于输出日志信息 //这里的args ...interface{}代表可以传任一个不同类型的参数 func (l LogGer) outLog(level logLevel, args ...interface{}) { if !l.eqLevel(level) { return } //看哪里调用这个函数了,哪里出错哪里调用,为了记录下出错的文件行号 _, file, line, ok := runtime.Caller(2) file = strings.Split(file, "/")[len(strings.Split(file, "/"))-1] if !ok { return } filestr, _ := downloadLevel(level) fmt.Printf("[%s] [%s] [文件:%s] [行号:%d] 附加信息:", time.Now().Format("2006-01-02 15:03:04"), filestr, file, line) //对传进来的不定个参数进行解析 for _, v := range args { fmt.Print(v) } fmt.Printf("\n") }
4.实现函数多返回值
这里是在编写日志系统的时候写的一个输出日志的函数
代码如下(示例):
//返回int类型与错误类型 func judgeName(name string) (int, error) { if name=="jack"{ return 0,nil } return -1, errors.New("传进来的不是jack") }
二、什么是Go语言方法?
方法与函数有一定的区别,接口的话有所属的结构体作为接受者,相应的对象可以调用该方法,函数只实现了一定的功能,不能使用对象直接调用。
1.简单实现一个方法
代码如下(示例):
// 定义一个结构体并添加方法 type user struct { name string age int speak_array string } //属于结构体的方法 //这里的(Someone user)Someone是接受者名,user是类型还可以是user指针类型 func (Someone user) speak() { fmt.Printf("%s说:我今年%d岁,%s\n", Someone.name, Someone.age, Someone.speak_array) }
二、什么是函数闭包?
func getSuperS() { //创建一个函数变量数组 var temp [3]func() int j := 0 for i := 0; i < 3; i++ { //直接使用当前所处环境中的j temp[i] = func() int { j++ return j } } /* 函数闭包使用的是该匿名函数所处环境的变量,如果变量重新声明 就导致匿名函数使用的变量不同,结果也就是不再共享一个变量 j定义在for外部,每次生成匿名函数使用的都是使用的同一个j (在for循环内部改变j的值不会影响该性质) j定义在for循环内部,每一次循环将产生一个新的j变量,三个匿名函数使用的也就不是同一个j了 */ fmt.Println(temp[0](), temp[0](), temp[0]()) fmt.Println(temp[1](), temp[1](), temp[1]()) fmt.Println(temp[2](), temp[2](), temp[2]()) }
总结
Go语言是一门面向过程编程语言,但是合理的使用函数也可以达到与面向对象编程语言类似的结果,Go语言函数灵活,操作也较为方便。