golang-function

函数定义

函数声明

func function_name( [parameter list] ) [return_types] {
函数体
}

/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {...}

下面示例为 float64 基本类型扩充了方法IsEqual,该方法主要是解决精度问题。 其方法调用方式为: a.IsEqual(double) ,如果不扩充方法,我们只能使用函数IsEqual(a, b float64)

//定义新的类型double,主要目的是给float64类型扩充方法
type double float64

//判断a是否等于b
func (a double) IsEqual(b double) bool {
var r = a - b
if r == 0.0 {
return true
} else if r < 0.0 {
return r > -0.0001
}
return r < 0.0001
}

//判断a是否等于b
func IsEqual(a, b float64) bool {
var r = a - b
if r == 0.0 {
return true
} else if r < 0.0 {
return r > -0.0001
}
return r < 0.0001
}

func main() {
var a double = 1.999999
var b double = 1.9999998
fmt.Println(a.IsEqual(b))
fmt.Println(a.IsEqual(3))
fmt.Println( IsEqual( (float64)(a), (float64)(b) ) )

}

函数返回多个值

func swap(x, y string) (string, string) {
return y, x
}

func main() {
a, b := swap("Mahesh", "Kumar")
fmt.Println(a, b)
// 有时候只关心某一个返回值,可以把其他的返回值赋给_
_, b:= swap("a","b")

}

支持给返回值命名后,实际上就是省略了变量的声明,return时无需写成return n,err 而是将直接将值返回

func ReadFull(r Reader, buf []byte) (n int, err error) {
for len(buf) > 0 && err == nil {
var nr int
nr, err = r.Read(buf)
n += nr
buf = buf[nr:]
}
return
}

值,引用传参

/* 定义交换值函数*/
func swap(x *int, y *int) {
var temp int
temp = *x /* 保持 x 地址上的值 */
*x = *y /* 将 y 值赋给 x */
*y = temp /* 将 temp 值赋给 y */
}

/* 调用 swap() 函数
* &a 指向 a 指针,a 变量的地址
* &b 指向 b 指针,b 变量的地址
*/
swap(&a, &b)

一维数组传参

下面两种方式

void myFunction(param [10]int)
{
}

void myFunction(param []int)
{
}

其他传参

入参中,如果连续的参数类型一致,则可以省略连续多个参数的类型,只保留最后一个类型声明。

// 入参a和b均是float64数据类型
func IsEqual(a, b float64) bool
func IsEqual(a, b float64, accuracy int) bool

变参:入参支持变参,即可接受不确定数量的同一类型的参数

// 参数args是的slice,其元素类型为int 。经常使用的fmt.Printf就是一个接受任意个数参数的函数
func Sum(args ...int)
fmt.Printf(format string, args ...interface{})

函数的使用

函数作为值

func main(){
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}

/* 使用函数 */
fmt.Println(getSquareRoot(9))

}

函数闭包

Go 语言支持匿名函数,可作为闭包。匿名函数是一个”内联”语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:

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
1
2

defer 延迟函数

延迟执行,在声明时不会立即执行,而是在函数return后时按照后进先出的原则依次执行每一个defer。这样带来的好处是,能确保我们定义的函数能百分之百能够被执行到,这样就能做很多我们想做的事,如释放资源,清理数据,记录日志等