Go语言之路————func
Go语言之路————func
- 前言
- 1.最基本的方法定义
- 2.方法中参数的传递
- 3.方法中的返回值
- 4.匿名方法
- 5.闭包的概念
- 6.defer关键词
前言
- 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触Go,到后面能正常完成工作上的业务开发的过程,如果你也是个小白或者转Go语言的,希望我这篇文章对你有所帮助。
- 有关go其他基础的内容的文章大家可以查看我的主页,接下来主要就是把这个系列更完,更完之后我会在每篇文章中挂上连接,方便大家跳转和复习。
本文我会详细的讲述go中的方法的用法,都是一些最常用的,必须要掌握的知识点,且随我娓娓道来。
1.最基本的方法定义
go中的方法,基本都用func关键词来声明的(特殊情况用var声明),下面这个代码,就表示了一个无返回值,无参数的一个方法
func test1() {
}
var test2 = func() {
}
它类似于什么呢,我给你举个例子,这下看懂了吧
public void test1() {
}
2.方法中参数的传递
go中方法的参数传递,也是名字在前,类型在后
func test1(a int, b string) {
fmt.Println(a, b)
}
func main() {
test1(1, "2")
}
go中变长参数,跟Java其实差不多用…来表示,只是前后的问题
func test3(b ...int32) {
fmt.Println(b)
}
func main() {
test3(1, 2, 3)
}
//输出:[1 2 3]
3.方法中的返回值
go中方法的返回值,也是比较简单的,分为普通返回值和带参数的返回值,当然也可以没有返回值,没有返回值就不写,不用加void字段
-
普通返回值
我们新建一个方法addNum,返回两数相加之和func addNum(a, b int) int { return a + b } func main() { num := addNum(1, 2) fmt.Println(num) //输出为3 }
通过这个例子我们能看到,go中的返回值是跟在参数后面、左花括号之前的,这是它的语法,如果用Java来比较的话:func addNum(a, b int) int {},等于public int addNum(int a,int b),这样一说大家都清楚了吧。
-
带参数返回值
当然,go中还有另一种返回方式,就是你可以指定返回的值,我们稍微改写下addNum方法,看下面这个例子func addNum(a, b int) (c int) { c = a + b return } func main() { num := addNum(1, 2) fmt.Println(num) //输出3 }
通过这个例子我们看到,如果你要指定返回值c,那么在参数后面,你要用括号把返回值扩起来,并且指定类型就好了。
思考一下:我上面的return后面没有任何返回,如果代码改成这样返回什么func addNum(a, b int) (c int) { c = a + b return 0 }
最后答案是输出0,即使我们上面返回值指定了c,但是用return的话会将0赋值给c,最后返回固定就是0,随便你传什么参数。
-
多个返回值
go中支持一个函数返回多个值,多个值我们也要用括号包起来,并指明类型,看看下面这个例子func moreReturn(a, b int) (c, d int) { return a, b } func main() { num1, num2 := moreReturn(1, 2) fmt.Println(num1, num2)//输出1,2 }
举一反三,结合上面第二点带参数返回值,我们代码还可以写成这样,输出也是1,2
func moreReturn(a, b int) (c, d int) { c = a d = b return } func main() { num1, num2 := moreReturn(1, 2) fmt.Println(num1, num2) }
PS:go中的方法是没有重载的,意思不能有相同名字、但是参数不同的两个方法。
4.匿名方法
go中的匿名方法,类似与Java中的匿名类(Java8之后的lamda表达式有匿名方法那味了),就是没有名字的方法,我们直接看下面例子:
func main() {
func() {
fmt.Println(2)
}()
}
//输出2
由于没有名字,那说明我们是不能调用的,只有写在代码逻辑里表示立即执行,通常结合go关键词用(后面会讲),需要注意的就是我这里写的格式,在代码最后有个括号()表示传参调用,可能这样有点抽象,我们看看下面一个有参数的例子你就知道了
func main() {
func(a, b int) {
fmt.Println(a + b)
}(1, 2)
}
代码输出为3,最后面括号里面的(1,2)就代表调用传参。
5.闭包的概念
go中闭包的概念,类似于Java中的Lamda 表达式,它是一种高级语法,与匿名函数一起使用,闭包 = 函数 + 环境引用吗
我们看看下面的例子,这就是一个闭包函数
func main() {
result := cal(1)
for i := 0; i < 10; i++ {
fmt.Println(result())
}
}
func cal(i int) func() int {
return func() int {
i = i + 1
return i
}
}
怎么来理解呢,我们先定义一个方法叫做cal(),接收一个int参数i,返回值是一个方法,你没听错,方法也能当做返回值。这个方法获取到参数i,然后作+1操作,结合上面我们提出来的概念:闭包 = 函数 + 环境。我们可以将cal()方法整体看做一个环境,我们main方法中调用cal,传入参数1,这个1在这个环境里面的,我们每次做了+1操作,这个环境中的1也会跟这改变,所以我们拿到cal的返回值,它是一个函数,我们循环调用这个函数10次,就会得到一个整齐的序列
最后我们的输出结果就是:
2
3
4
5
6
7
8
9
10
11
6.defer关键词
defer是go中的一个关键词,它的作用就是延迟调用,在哪延迟,在方法返回之前调用。看看下面这个例子
func main() {
deferTest()
}
func deferTest() {
defer fmt.Println(1)
fmt.Println(2)
fmt.Println(3)
}
//输出2,3,1
都是两个Println输出,但是第一个我前面加了defer关键词,所以导致它被延迟调用了,只有当执行完deferTest中所有代码逻辑,return之前,才会调用defer关键词修饰的代码,通常我们defer后面跟一个方法。
如果多个defer,其中的调用逻辑是先进后出,是一个栈的模式
func deferTest() {
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println(4)
fmt.Println(5)
}
//输出结果为:4,5,3,2,1