Java转Go—09函数

函数

函数是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),表示返回两个整形。

运行结果:

Java转Go—09函数
运行结果

函数调用

函数调用很好理解,例如上面的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
}

运行结果:

Java转Go—09函数
运行结果

由上可见,由于函数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
}

运行结果:

Java转Go—09函数
运行结果

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

延迟调用

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

代码示例:

package main

import "fmt"

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

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

运行结果:

Java转Go—09函数
运行结果

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

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

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

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

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


原文始发于微信公众号(良猿):Java转Go—09函数

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/215846.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!