函数是程序的基本代码块,函数是解决一类问题的步骤的有序组合,java和go都类似 需要提供一个函数入口 也就是main函数
java程序里面函数被称之为方法,一般情况下定义一个方法包含以下语法
修饰符 返回值类型 方法名(参数类型 参数名){方法体 return 返回值}
修饰符:修饰符是可以选择的,告诉编译器该如何调用该方法,定义了该方法的访问权限
返回值类型:有些方法需要有返回值,需要返回值的方法必须明确指定返回值的类型,没有返回值则用void关键字声明
方法名:是方法的实际名称,方法名称和参数列表共同构成方法签名
参数类型,参数就像是一个占位符,传递值给参数,这个值被称为实参或变量。参数列表指的是方法的参数类型,顺序和参数的个数,参数是可以选择的可以一个参数都没有
方法体:方法体包含具体的语句,定义了该方法的功能
Go语言函数
函数格式定义如下:
func function_name( [parameter list] ) [return_types] { 函数体 }
在Go语言里面方法都被称之为函数,函数由func关键字声明,后面跟着方法的名称,参数列表,最后是返回值类型,注意:go里面的函数允许有多个返回值,在java中我们的方法只允许有一个返回值,当有多个返回值的时候我们一般会封装到一个数据类型中返回来,这一点Go就要比java方便多了,当我们需要返回多个参数的时候可以直接返回不需要去另外维护一个数据类型来返回
- func:函数由 func 开始声明
- function_name:函数名称,函数名和参数列表一起构成了函数签名。
- parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
- return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
- 函数体:函数定义的代码集合。
-
实例
以下实例为 max() 函数的代码,该函数传入两个整型参数 num1 和 num2,并返回这两个参数的最大值:
/* 函数返回两个数的最大值 */ func max(num1, num2 int) int { /* 声明局部变量 */ var result int if (num1 > num2) { result = num1 } else { result = num2 } return result }
函数参数
函数如果使用了参数,该变量可以称之为函数的形参这个和java类似,形参就像定义在函数体内的局部变量
调用函数,可以通过两种方式来传递参数
值传递:值传递是指调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数的修改将不会影响到实际的参数
引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数当中,那么在函数中对参数的修改将会影响到实际参数
其实这两个传参和java差不多,只不过在java中 基础数据类型默认是使用的值传递,而引用类型使用的是地址传递,在Go语言中默认都是值传递,如果需要使用值传递则需要用*显示的声明
Go 语言函数闭包
Go语言支持匿名函数,可以作为闭包。匿名函数是一个内联语句或者表达式,匿名函数的优越性在于可以直接使用函数内的变量,不必申明。看下实例
package main import "fmt" func getSequence() func() int { i:=0 return func() int { i+=1 return i } } func main(){ /* nextNumber 为一个函数,函数 i 为 0 */ nextNumber := getSequence() /* 调用 nextNumber 函数,i 变量自增 1 并返回 */ fmt.Println(nextNumber()) fmt.Println(nextNumber()) fmt.Println(nextNumber()) /* 创建新的函数 nextNumber1,并查看结果 */ nextNumber1 := getSequence() fmt.Println(nextNumber1()) fmt.Println(nextNumber1()) }
//实际输出结果 1 2 3
这个例子困扰我半天,go语言默认是值传递,没有显示的声明就因该是值在传递应当不会影响到原来的值
后来经过同事的开解,我们可以这样理解,吧getSequence理解成一个java的一个类,i理解成java的一个全局变量
我们调用getSequence()返回的是这个类的对象,后面的操作都是对对象里面的值在操作。