由浅到深认识Go语言(6):函数

本文介绍了作者开源的SpringBoot项目初始化模板,涵盖了函数的使用(单值和多值返回、延迟调用、递归和匿名函数),强调代码复用和配置管理的重要性。通过实例展示了如何在Go语言中实现这些功能,适合初学者学习和实践。
摘要由CSDN通过智能技术生成

该文章Github地址:https://github.com/AntonyCheng/go-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Go语言(5):控制流程

7.函数

7.1.基础函数

函数是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集;

使用函数可以加强代码的复用性,提高程序编写的效率;

基本结构:

//函数返回单个值的情况(和其他语言相似)
func 函数名(形参名 数据类型,……) 返回值类型 {
	函数体……()
    return 返回值类型变量
}
//或者在函数签名处指定返回值变量,指定同时也就创建了该变量,所以函数体中不声明该返回值变量
func 函数名(形参名 数据类型,……) (指定返回变量名 返回值类型) {
    函数体……
    return 指定返回变量
}

//函数返回多个值的情况
func 函数名(形参名 数据参数,……) (返回值1类型,返回值2类型,……) {
    函数体……
    return 返回值1,返回值2,……
}
//调用函数时:变量1,变量2,…… = 函数名(参数……)
//如果有不需要的返回值,使用‘_’进行接收
//或者也能够指定返回值变量,和单个值的情况一样

函数调用时需要实参位置和形参位置相对应;

不定参数列表基本结构:

//不定参数列表的基本结构
func 函数名(参数列表名 ...T类型){
    函数体……
}

//不定参数列表和已知参数列表混用
func 函数名(已知参数名 类型,……,参数列表名 ...T类型){
    函数体……
}
//已知的参数需要写在不定参数之前

此处的函数列表是一个T类型的数组,此时就可以用到 for range 结构进行遍历;

示例如下:

package main

import "fmt"

func main() {
	TestSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
}
func TestSum(args ...int) {
	sum := 0
	for _, value := range args {
		sum += value
	}
	fmt.Printf("sum = %d\n", sum)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

函数作用域:

  • 定义在函数内部的变量成为局部变量,局部变量的作用域在函数内部;
  • 所谓的全局变量:既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量,也就是定义在函数外部的变量就是全局变量;
  • 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量;

全局变量中声明并且初始化一个值,不能使用 a:=10 的形式;

案例一:

定义一个函数,计算1-100的和;

package main

import "fmt"

func main() {
	sum()
}
func sum() {
	num := 0
	for i := 0; i <= 100; i++ {
		num += i
	}
	fmt.Printf("num = %d\n", num)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:

定义一个函数,计算1-n的和;

package main

import "fmt"

func main() {
	init := 0
	fmt.Println("请输入一个数:")
	fmt.Scan(&init)
	sum(init)
}
func sum(init int) {
	num := 0
	for i := 0; i <= init; i++ {
		num += i
	}
	fmt.Printf("num = %d\n", num)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例三:

输入一个人的姓名,并且获取语数外成绩,利用不定参数形式计算总成绩;

package main

import "fmt"

func main() {
   name := ""
   chinese := 0
   mathematics := 0
   english := 0
   fmt.Println("请输入你的姓名:")
   fmt.Scan(&name)
   fmt.Println("请以此输入你的语数外成绩:")
   fmt.Scan(&chinese, &mathematics, &english)
   TestSum(name, chinese, mathematics, english)
}
func TestSum(name string, args ...int) {
   sum := 0
   for _, value := range args {
      sum += value
   }
   fmt.Printf("%s 的总成绩为 %d\n", name, sum)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例四:

用函数模拟用户注册,当用户输入完用户名,密码和邮箱后,进行校验。如果发现用户名,密码和邮箱是空的,则给出“信息不能为空,用户注册失败”的提示,否则,进行邮件发送,并给出“用户注册成功”的提示。

package main

import "fmt"

func main() {
   register()
}

func register() {
   username := ""
   password := ""
   email := ""
   fmt.Println("请输入用户名:")
   fmt.Scan(&username)
   fmt.Println("请输入密码:")
   fmt.Scan(&password)
   fmt.Println("请输入邮箱:")
   fmt.Scan(&email)
   if checkInfo(username, password, email) {
      sendEmail()
      fmt.Println("用户注册成功!")
   } else {
      fmt.Println("信息不能为空,用户注册失败!")
   }
}

func checkInfo(username string, password string, email string) bool {
   if username != "" && password != "" && email != "" {
      return true
   } else {
      return false
   }
}

func sendEmail() {
   fmt.Println("邮件已经发送")
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.2.延迟调用

如果想要一个语句延迟调用,那么就需要用到 defer 关键字,例如:

package main

import "fmt"

func main() {
   defer fmt.Println("Hello, world!")
   fmt.Println("GoLang")
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当有多个 defer 关键字时,被标识的所有语句会安装 LIFO(后进先出)的方式进行调用;

package main

import "fmt"

func main() {
   defer fmt.Println("Hello, world!")
   fmt.Println("GoLang")
   defer fmt.Println("Hello, China!")
   fmt.Println("Java")
   defer fmt.Println("Hello,USA!")
   fmt.Println("C++")
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.3.递归函数

递归函数简介

如果一个函数在内部调用自身,这个函数就是递归函数;

举例说明递归函数语法

寻找自己的排数;

package main

import "fmt"

func main() {
   c := test(3)
   fmt.Println(c)
}

func test(n int) int {
   //只有第一排的人才知道自己的排数
   if n == 1 {
      return 1
   }
   //如果不是第一排,就问一下前一排的人
   r := test(n - 1)
   fmt.Println("前一排的排数:", r)
   //把前一排的排数+1,计算出自己的排数
   return r + 1
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例一:

计算一个数的阶乘;

package main

import "fmt"

var a int = 1

func main() {
   calcFactorial(5)
   fmt.Println(a)
}

func calcFactorial(n int) {
   if n == 1 {
      return
   }
   a *= n
   calcFactorial(n - 1)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.4.匿名函数

匿名函数的定义格式如下:

func(参数列表)(返回参数列表){
  函数体
}(实参列表)

//必要的形式框架如下
func (){
    
}()

匿名函数的定义就是没有名字的普通函数定义。

示例如下:

package main

import "fmt"

func main() {
   a := 1
   b := 2
   sum := func(a int, b int) int {
      return a + b
   }(a, b)
   fmt.Println("sum =", sum)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一章:由浅到深认识Go语言(7):数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值