GoLang学习笔记之基础语法(四):函数

目录

前言

一、Go语言中函数如何定义?

1.函数的定义方式

2.函数的类型

二、函数的使用

1.匿名函数 

2.回调函数

3.闭包

4.递归

三、练习

1.构造一个闭包,输入文件名时,为其添加相应后缀,如输入文件名"hello",输出"hello.jpg"

2.使用递归实现爬楼梯:即某人一次只能爬1级或2级阶梯,当输入阶梯数量i时,要求输出一共有多少种走法去爬楼梯。

总结


前言

本文将详细介绍GO语言中的函数使用,包括函数的定义,函数的类型,匿名函数,回调函数,闭包以及递归函数的使用等。



一、Go语言中函数如何定义?

1.函数的定义方式

在Go语言中,函数通过func关键字进行定义或声明。函数具有参数列表和返回值列表,参数列表可以有0个或多个参数,返回值列表也可以有0个或多个返回值

2.函数的类型

// 1.函数的4种类型,无参无返回值,无参有返回值,有参无返回值,有参有返回值
func f1 ()(){
	fmt.Println("I am f1()")
}

func f2()int{
	fmt.Println("I am f1(),i will return an int num")
	return 5
}

func f3(i int){
	fmt.Printf("I am f3(),i got an int num:%v\n",i)
}

func f4(i int)int{
	fmt.Printf("I am f3(),i got an int num:%v,i will return it \n",i)
	return i
}

func main(){
    fmt.Printf("%T,%T,%T,%T\n",f1,f2,f3,f4) //输出:func(),func() int,func(int),func(int) int
}

函数的类型包括其参数列表及返回值列表 



二、函数的使用



1.匿名函数 

  • 有时候我们想要完成某一特定功能,但该功能只在一个包中用到几次,我们可以不用将其封装为包级别的函数,而是使用匿名函数
  • 匿名函数,就是可以省略函数名的函数
    r := func (i int)int{ // 匿名函数不需要函数名
    		return i
    	}(5) // 匿名函数通过后面的()向函数传参
    	fmt.Println(r) // 输出5



2.回调函数

go语言是一种强类型语言,我们知道了函数的类型,就可以将其作为参数传入另一个函数,我们称这种函数为回调函数。

func f5(i int,callback func(i int)bool){
	if callback(i){
		fmt.Println("i am more than 5")
	}else{
		fmt.Println("i am less than 5")
	}
}

func main(){
	callback := func(i int)bool{
		if i > 5{
			return true
		}
		return false
	}
	f5(7,callback) // 输出i am more than 5
}

3.闭包

刚刚讨论了函数作为函数参数的情况,现在再来讨论函数作为返回值的情况。在一个函数中返回值是另外一个函数,我们称之为闭包。

  • 闭包的理解:内部函数访问外部函数的变量
  • 闭包的作用:改变临时变量的生命周期
  • 闭包示例
    // 考虑这样一种应用场景,公司其他部门的同事提供给你API,该API要求输入参数为一个func()类型(无参数无返回值)
    // 现在你有一个func(i int)类型的函数,如何才能调用上述的API呢,这就需要用到闭包
    func f6(f func()){
    	fmt.Println("I am f6()")
    	f()
    }
    
    func f7(i int)func(){
    	return func(){
    		// 可以看到,该匿名函数中并没有关于变量i的声明与定义,它引用了外部f7()的变量,延长了变量i的生命周期
    		fmt.Printf("I am f7(),i have a parameter:%v\n",i)
    	}
    }
    
    func main(){
        f6(f7(9)) // 输出:I am f6() \n I am f7(),i have a parameter:9
    }

4.递归

  • 函数在处理过程中调用自身,称之为递归。
  • 递归必须有结束条件,否则会陷入死循环。
  • 使用递归前,最好把问题进行数学抽象
  • 递归示例:斐波那契数列
    // 首先进行数学抽象,明确该函数返回值的意义
    // 该函数返回值是斐波那契数列中第i个位置的值
    // 根据斐波那契数列的数学规律,我们知道第i个位置的值等于其前两个位置值之和,即fibonacci(i-1)+fibonacci(i-2)
    // 当处于第一或第二个位置时,由于其前面不足两个元素,因此要单独考虑
    func fibonacci(i int)int{
    	if i <= 2{
    		return 1
    	}
    	return fibonacci(i-1)+fibonacci(i-2)
    }
    
    func main(){
        for i:=1;i<=10;i++{
    		fmt.Printf("%v ",fibonacci(i)) // 输出:1 1 2 3 5 8 13 21 34 55
    	}
    	fmt.Println("")
    }

三、练习

1.构造一个闭包,输入文件名时,为其添加相应后缀,如输入文件名"hello",输出"hello.jpg"

func addSuffix(suffix string)func(name string)string{
	return func(name string)string{
		if strings.HasSuffix(name,suffix){
			return name // 如果名字中自带了该后缀,则无需添加
		}
		return name+suffix // suffix不是该函数内的变量,相当于使用了外部变量,延长其生命周期
	}
}

func main(){
    addJpg := addSuffix(".jpg") // 返回值是一个func(string)string类型函数,其保存了外部变量suffix的值为:".jpg"
	addPng := addSuffix(".png")  // 返回值是一个func(string)string类型函数,其保存了外部变量suffix的值为:".png"
	fmt.Println(addJpg("Hello")) // 输出: Hello.jpg
	fmt.Println(addPng("Go")) // 输出: Go.png
}

2.使用递归实现爬楼梯:即某人一次只能爬1级或2级阶梯,当输入阶梯数量i时,要求输出一共有多少种走法去爬楼梯。

  • 首先对问题进行抽象,明确函数的返回值是什么
  • 根据题目可知,函数的返回值为i层阶梯共有多少种走法
  • 接下来考虑我们第一步如何走
    • 如果我们第一步只走一级,那剩下i-1级阶梯,共有climb(i-1)种走法
    • 如果我们第一步走2级阶梯,那剩下i-2级阶梯,共有climb(i-2)中走法
    • 所以i层阶梯我们一共可以有climb(i-1)+climb(i-2)种走法
  • 最后考虑特殊情况,如果阶梯只有一级,那只有一种走法,阶梯有2级,只有两种走法。
  • 代码实现如下
    func climb(i int)int{
    	if i == 1 || i == 2{  //如果只有1级阶梯,只有一种走法,2级阶梯,只有2种走法
    		return i
    	}
    	return climb(i-1)+climb(i-2) // climb(i-1)表示走了1级阶梯后还有多少种走法,climb(i-2)表示走了(i-2)级阶梯后还有多少走法
    }
    
    func main(){
        fmt.Println(climb(5)) // 输出8
    }



总结

Go语言中函数通过关键字func声明,参数列表和返回值列表都可以有0个或多个元素。函数的类型包括其参数列表和返回值列表。当某些功能仅在特定场合下使用时,可使用匿名函数。当函数作为参数时,称之为回调函数。当函数作为返回值时,称为闭包。函数在实现时调用自身,称为递归。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值