Go语言入门【8】函数

函数

函数是go语言中最基础的代码块,通常将需要当做一个整体执行的任务抽象成一个函数,例如前面用到的len、cap和append等都是系统定义好的函数,还有go里面的main函数,他是go程序运行的入口函数,是必不可少的一个主函数,而且go语言中有且仅有一个main主函数。

函数声明

函数声明时需要指定函数名称、参数列表和返回列表。

声明函数时需要使用关键字func,函数声明语法如下:

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

函数名:在其他地方调用时需要用到的名称

参数列表:当函数被调用时可以根据参数列表传递对应的参数,在函数体中可以使用参数,参数列表需要指定参数名和参数类型,参数个数是可选的,可以没有参数也可以有多个参数。

返回列表:当函数执行完成之后返回的数据,返回列表需要指定返回类型,返回列表可选,可以没有返回值,也可以有多个返回值。

函数体:函数核心,需要执行的代码逻辑。

代码示例:

package main

import "fmt"

func main() {
  result := add(1,2)
  fmt.Println(result)
}

// 声明一个函数,传入两个int类型整数,返回两个数相加的和
func add(n1 int, n2 int) int {
  return n1 + n2
}

如上定义了一个函数add,返回两数之和,当两个参数的类型一样时,还可以写成这样func add(n1, n2 int),在main函数中调用该函数传入两个整数,返回的result结果为3。

在go语言中,函数可以有多个返回值。

代码示例:

package main

import "fmt"

func main() {
  add, sub := addAndSub(1,2)
  fmt.Println(add)
  fmt.Println(sub)
}

// 声明一个函数,传入两个int类型整数,返回两个结果,一个是两数之和,一个是两数之差
func addAndSub(n1 int, n2 int) (add int, sub int) {
  add = n1 + n2
  sub = n1 - n2
  return add, sub
}

如上所示,声明一个函数addAndSub,该函数有两个返回值,一个是两数之和,一个是两数之差,当有多个返回值时,返回值列表写法可以和参数列表写法一致,在返回值列表中声明了的返回值明,在函数体中可以直接使用,例如变量add和sub在函数体中可以不用重新声明,直接使用即可,返回列表同样还可以只写返回类型,不写具体的变量名,例如func addAndSub(n1 int, n2 int) (int,int),表示返回两个整形。

运行结果:

函数调用

函数调用很好理解,例如上面的addAndSub函数,在main函数中调用时直接写函数名即可,需要注意以下几点:

  1. 如果函数有多个参数,则在调用函数传参数时需要注意参数个数和顺序,以及参数类型。
  2. 如果函数有多个返回值,则同样需要以多个变量接收,多个变量之间用逗号隔开,同样也可以只接收其中部分返回值,忽略其他返回值,例如add, _ := addAndSub(1,2),表示只接收和的返回值,忽略差的返回值。

值传递和引用传递

在函数中,传参最重要的部分就是值传递和引用传递。

  • 值传递:在调用函数时,将实际参数拷贝一份传递到函数中,在函数中对参数的改变不会影响到实际的参数。
  • 引用传递:在调用函数时,将实际参数的地址传递到函数中,在函数中对参数的操作会影响到实际的参数。

值传递示例:

package main

import "fmt"

func main() {
  // 定义局部变量
  num := 1
  fmt.Println("改变前num的值:", num)
  // 将实际参数传递给函数change
  change(num)
  fmt.Println("改变后num的值:", num)
}

// 定义一个函数,将传递进来的参数的值变为10
func change(num int) {
  num = 10
}

运行结果:

由上可见,由于函数change是值传递,所以在函数内部对参数的改变并不会影响到实际参数,而且在go语言中默认使用的就是值传递。

引用传递示例:

package main

import "fmt"

func main() {
  // 定义局部变量
  num := 1
  fmt.Println("改变前num的值:", num)
  // 将实际参数传递给函数change
  change(&num)
  fmt.Println("改变后num的值:", num)
}

// 定义一个函数,将传递进来的参数的值变为10
func change(num *int) {
  *num = 10
}

运行结果:

当使用引用传递时,函数的参数类型为*int,在main函数中调用该函数时,传递的是实际参数在内存中的存放地址,因此在change函数中对参数的改变会影响到实际参数。

延迟调用

在go语言函数中,可以对函数进行延迟调用,延迟调用需要使用到defer关键字,在函数调用前面加上该关键字,则该函数不会立即被调用,而是会延迟调用。

代码示例:

package main

import "fmt"

func main() {
  defer delay()
  fmt.Println("主函数执行...")
}

func delay() {
  fmt.Println("延迟调用...")
}

运行结果:

如上所示,定义了一个函数delay,虽然该函数在main主函数中的第一行就被调用了,但是该函数中的打印却是在主函数打印出主函数执行后才进行打印,这就是延迟调用,延迟调用会等待主函数都执行完成之后再执行。

如果一个主函数中同时有多个延迟调用,那么最后的执行顺序会按照代码的顺序逆序执行。 例如以下代码:

defer delay1()
defer delay2()
defer delay3()

这三个延迟调用函数,在主函数执行完成之后,会按照delay3delay2delay1的顺序执行。

延迟调用可以用于数据库连接关闭函数,在连接数据库之后立马延迟调用数据库连接关闭函数,这样数据库连接不会立马被关闭,而且也不会导致写完代码之后忘记关闭数据库连接。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeJR

如果觉得有用请赏一个呗!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值