【GoLang】2.3 函数

基本语法

  GoLang的函数声明,返回类型写在最后,确实不符合我以前的习惯,因为我C和Java用得多,这两种语言,返回类型都是写在函数/方法名前面的,不过不习惯也得练习适应啊。

package main

import "fmt"

func main() {
	fmt.Println(cubic(3))
}

func cubic(x rune) rune {
	return x * x * x
}

  执行结果:

27

  所以可以总结下函数的声明就是这么几部分组成:

  1. func关键字
  2. 函数名
  3. 参数列表
  4. 返回值列表
  5. 函数体

多返回值

  多返回值,我在python里已经体验过了,但是Python的多返回值是将返回值包装为元组,如果拿多个变量来接,就把元组拆开,再赋值到多个变量。Go的多返回值函数,是必须得全部接全部返回值,如果不需要用那么多返回值,就需要用下划线来占位,如。

package main

import "fmt"

func main() {
	a, _ := divmod(7, 3)
	fmt.Println(a)
}

func divmod(x rune, y rune) (rune, rune) {
	return x / y, x % y
}

  输出:

2

一等公民

  在Go里函数是一等公民,是一个特殊的类型。最明显的是可以将一个变量定义为函数类型,这样程序的灵活性大大提高,或者说将函数赋值给一个变量。我举个例子,我用一个函数产生抛物线函数,然后调用抛物线函数:

package main

import "fmt"

func main() {
	fun := parabola(3, 4, 5)
	fmt.Println(fun(3))
}

func parabola(a rune, b rune, c rune) func(rune) rune {
	return func(x rune) rune {
		return a*x*x + b*x + c
	}
}

  上述代码执行结果为:

44

匿名函数

  其实上面的例子里已经有了匿名函数了。上例的匿名函数是在函数体内定义的。能否在包下定义呢?是可以的,但是只能定义为变量,不能定义为常量,如:

package main

import "fmt"

var porabola = func(x rune) rune {
	return 3*x*x + 4*x + 5
}

func main() {
	fmt.Println(porabola(6))
}

  执行结果:

137

  其实我还忘了介绍匿名函数的一个特性,就是匿名函数如果在函数体内定义,可以直接调用局部变量,并且可以修改局部变量的值。这点和java不一样,java的匿名内部类和lambda表达式是不能修改局部变量的值的。对于GoLang的这点,我举个例子:

package main

import "fmt"

func main() {
	x := 1
	increment := func() {
		x++
	}
	increment()
	fmt.Println(x)
}

  执行以后,输出为2,说明x已经加1了。

可变参数

  许多编程语言有变长参数,最明显的是C语言的printf函数,java也有三个点号的函数定义。而Python就更复杂了,有两种形式的,*args和**kwargs。在GoLang中,这类函数叫Variadic Functions,fmt包下的Println就是这样的函数。这样的函数我们也可以写一个练练,不过需要提前学习下for循环语法了。我是写了一个连乘函数练手哈:

package main

import "fmt"

func main() {
	fmt.Println(prod(3, 4, 5, 6, 7))
}

func prod(vars ...rune) rune {
	var p rune = 1
	for _, v := range vars {
		p *= v
	}
	return p
}

  输出结果:

2520

返回值命名

  这是goLang语言特殊的地方,其他的编程语言,函数或方法定义返回值的时候只需要定义类型就可以了。GoLang也可以只定义返回值的类型,但是GoLang可以同时定义返回值的变量名。指定了变量名,那就意味着定义了变量,同时也意味着函数返回时只需要一个简单的return,return关键字后不需要再加任何变量了。我举个例子:

package main

import "fmt"

func main() {
	fmt.Println(multiply(3, 5))
}

func multiply(a rune, b rune) (c rune) {
	c = a * b
	return
}

  输出结果是15,因为在返回值列表里已经定义了返回值变量,所以return后面什么都不用写。但是这个return能不能省略呢?这是不可以的!会报语法错误。

init函数

  init函数和main函数应该一起讲的,但是main函数大家已经很熟悉了,所以只需要单独说说init函数,init函数在go文件里会在main函数之前执行,如以下例子:

package main

import "fmt"

func init() {
	fmt.Println("init")
}

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

  输出结果为:

init
Hello, world!

  确实验证了init在main函数之前执行。

注意事项

  1. 在学JSON那里我们会看到只有首字母大写的字段才能JSON序列化和反序列化。这是GoLang的做法,首字母大写的才是公有的,才能被其他包访问到,函数也是一样,如果希望函数被其他包调用,首字母应当大写。
  2. GoLang的函数不支持重载。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

醒过来摸鱼

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值