Golang的函数和闭包

多个参数

package main

import "fmt"

func add(x, y int) (ret int) {
 //x的类型省略,x和相邻的y同类型,返回值指定为ret int,如果返回值仅int,则可返回任意的int数据
	ret = x + y //ret直接使用,无须再定义
	return      //可以省略ret,不能省略return
}
func main() {
	ret := add(10, 20)
	fmt.Println(ret)
}

可变参数

package main

import "fmt"

//有一个整数参数x和一个可变参数nums,编写函数实现x是否在nums中出现
func hasX(x int, nums ...int) bool {
	for _, v := range nums {
		if x == v {
			return true
		}
	}
	return false
}
func main() {
	has := hasX(10, 12, 34, 65, 78)
	if has {
		fmt.Println("x出现在nums切片中")
	} else {
		fmt.Println("x没有出现在nums切片中")
	}
}

10会传参给x,12, 34, 65, 78会以切片形式传参给nums,在hasX函数体内可以将nums当作切片处理。

多个返回值

package main

import "fmt"

func addSub(x, y int) (int, int) {
	add := x + y
	sub := x - y
	return add, sub
}
func main() {
	ret1, ret2 := addSub(20, 10)
	fmt.Println(ret1, ret2)
}

addSub函数分别实现对传入参数相加和相减操作,并且返回两个结果,使用两个变量接受返回值。当然也可以对多个返回值指定名称,也可以如同省略参数类型一样省略返回值类型。

package main

import "fmt"

func addSub(x, y int) (add, sub int) {
	add = x + y
	sub = x - y
	return
}
func main() {
	ret1, ret2 := addSub(20, 10)
	fmt.Println(ret1, ret2)
}

定义函数类型

我们可以使用type关键字来定义一个函数类型,具体格式如下:

type calculation func(int, int) int

上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。

简单来说,凡是满足这个条件的函数都是calculation类型的函数,例如下面的add和sub是calculation类型。

func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}

add和sub都能赋值给calculation类型的变量。

var c calculation
c = add

被赋值的c变量,类型是main.calculation类型,c()等同于add()

package main

import "fmt"

type calculation func(int, int) int

func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}
func main() {
	var fun1, fun2 calculation
	fun1, fun2 = add, sub
	ret1 := fun1(20, 10)
	ret2 := fun2(20, 10)
	fmt.Printf("fun1:%T\tfun2:%T\n", fun1, fun2)
	fmt.Println(ret1, ret2)
}

函数作为参数

package main

import "fmt"

func add(x, y int) int {
	return x + y
}

func sum(x, y int, op func(int, int) int) (ret int) {
//sum函数共有x,y,op三个参数,op的类型是op func(int, int) int,sum函数的返回值是ret int
	ret = op(x, y)
	return
}
func main() {
	res := sum(10, 20, add)
	fmt.Println(res)
}

当然函数也可以作为函数的返回值,如下匿名函数部分。

匿名函数

go语言也可以将函数看做是对象,先看看匿名函数作为函数返回值

package main

import "fmt"

func bag() func() {
	return func() {
		fmt.Println("hello,world")
	}
}
func main() {
	fun := bag()
	fun()
}

如上,bag函数的返回值是一个匿名函数,定义fun变量接受这个匿名函数之后就可以调用它。

package main

import "fmt"

func bag() {
	func() {
		fmt.Println("hello,world")
	}()
}
func main() {
	bag()
}

如上,并不需要bag函数返回匿名函数,bag函数内需要立即调用,可直接在定义匿名函数体后加()进行立即执行。

当然,也可以写成如下形式

package main

import "fmt"

func bag() {
	fun:=func() {
		fmt.Println("hello,world")
	}
	fun()
}
func main() {
	bag()
}

闭包

闭包=函数+引用函数外变量

func adder() func(int) int {
	var x int
	return func(y int) int {
		x += y
		return x
	}
}

上述adder中的匿名函数就是闭包,该匿名函数使用了其外部变量x。

package main

import "fmt"

func closebag(base int) (func(int) int, func(int) int) {
	add := func(x int) int {
		base += x
		return base
	}
	sub := func(y int) int {
		base -= y
		return base
	}
	return add, sub
}
func main() {
	fun1, fun2 := closebag(200)
	a := fun2(10)
	b := fun1(20)
	fmt.Println(a, b)
}

上述closebag函数中的两个匿名函数分别使用了add、sub两个变量来接受,并且返回了这两个函数变量,在这两个匿名函数中都使用了其函数外部变量base。因此这两个匿名函数都属于闭包。

package main

import (
	"fmt"
	"strings"
)
//检查字符串name是否值由suff字符结尾,如果不是返回name+suff
func checkSuff(suff string) (func(string)string) {
//checkSuff的返回值是一个有string类型参数和string类型返回值的匿名函数
	return func(name string)string{
		if !strings.HasSuffix(name,suff){
			return name+suff
		}
		return name
	}
}

func main() {
	fun:=checkSuff(".doc")
	str:=fun("word")
	fmt.Println(str)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值