当前位置:网站首页>go慢速入门——函数
go慢速入门——函数
2022-07-30 21:09:00 【zy010101】
函数
go中的函数非常重要,因为go没有类那套东西,因此函数go中最重要的单元。go中函数声明形式如下所示:
func 函数名(参数列表)(返回值列表){
函数体
}
go中使用关键字func定义函数,函数名必须是合法的标识符。在go中,一个函数可以有多个返回值。函数体必须用花括号包起来。例如:
package main
import "fmt"
func main() {
// 程序的main入口函数必须不带任何输入参数和返回结果。
fmt.Println(add(1, 2))
fmt.Println(mul(3, 4))
}
func add(a int, b int) int {
//只有一个匿名返回值的时候,可以省略返回值列表外面的小括号;否则不能省略小括号。
var c = a + b
return c
}
func mul(a int, b int) (sum int) {
// 一个具名返回值,需要使用小括号。
sum = a * b
return // 由于在返回值列表中声明了返回值,因此在return后面可以省略掉sum。
}
函数参数和函数返回值是由标识符和类型组成的,不像变量定义的时候,需要关键字var。
Go不支持输入参数默认值。每个返回结果的默认值是它的类型的零值。
和普通的变量声明一样,如果若干连续的输入参数或者返回结果的类型相同,则在它们的声明中可以共用一个类型。例如:
func SquaresOfSumAndDiff(a, b int64) (s, d int64) {
// a,b,s,d都是int64类型。
return (a+b) * (a+b), (a-b) * (a-b)
// 上面这行等价于下面这行:
// s = (a+b) * (a+b); d = (a-b) * (a-b); return
}
注意,尽管在上面这个函数声明的返回结果都是具名的,函数体内的return关键字后仍然可以跟返回值。
函数调用的时候,一个实参值的类型不必一定要和其对应的形参声明的类型一样。 但如果一个实参值的类型和其对应的形参声明的类型不一致,则此实参必须能够隐式转换到其对应的形参的类型。
一个函数的声明可以出现在它的调用之前,也可以出现在它的调用之后。一个函数调用可以被延迟执行或者在另一个协程(goroutine,或称绿色线程)中执行。
函数调用的退出阶段
在Go中,当一个函数调用返回后(比如执行了一个return语句或者函数中的最后一条语句执行完毕), 此调用可能并未立即退出。一个函数调用从返回开始到最终退出的阶段称为此函数调用的退出阶段(exiting phase)。 函数调用的退出阶段的意义将在延迟函数中体现出来。
这是go语言的特色。
匿名函数
现在绝大多数的编程语言都支持匿名函数。匿名函数就是没有名称的函数,例如:
package main
func main() {
// 这个匿名函数没有输入参数,但有两个返回结果。
x, y := func() (int, int) {
println("This function has no parameters.")
return 3, 4
}() // 一对小括号表示立即调用此函数。不需传递实参。
// 下面这些匿名函数没有返回结果。
func(a, b int) {
println("a*a + b*b =", a*a + b*b) // a*a + b*b = 25
}(x, y) // 立即调用并传递两个实参。
func(x int) {
// 形参x遮挡了外层声明的变量x。
println("x*x + y*y =", x*x + y*y) // x*x + y*y = 32
}(y) // 将实参y传递给形参x。
func() {
println("x*x + y*y =", x*x + y*y) // x*x + y*y = 25
}() // 不需传递实参。
}
注意,在go中,不能再函数内定义函数,如果上面这些匿名函数不被直接调用,那么将会导致错误。上例中的最后一个匿名函数处于变量x和y的作用域内,所以在它的函数体内可以直接使用这两个变量。 这样的函数称为闭包(closure)。
实际上一个匿名函数可以被赋值给某个函数类型的值,从而我们不必在定义完此匿名函数后立即调用它,而是可以在以后合适的时候再调用它。
边栏推荐
- @Transactional注解在类上还是接口上使用,哪种方式更好?
- 新书上市 |《谁在掷骰子?》在“不确定性时代”中确定前行
- C语言中指针没那么难~ (1)【文章结尾有资料】
- 你需要知道的ES6—ES13开发技巧
- 弹性盒子模型
- Android Studio 实现登录注册-源代码 (连接MySql数据库)
- HJ85 longest palindrome substring
- [Limited Time Bonus] 21-Day Learning Challenge - MySQL from entry to mastery
- Mysql8创建用户以及赋权操作
- 数据指标口径不统一、重复开发?亿信ABI指标管理平台帮你解决
猜你喜欢
7、MySQL Workbench 导出导入数据库
【回归预测-CNN预测】基于卷积神经网络CNN实现数据回归预测附matlab代码
【深度学习】对迁移学习中域适应的理解和3种技术的介绍
LeetCode · 23. Merge K ascending linked lists · recursion · iteration
Niu Ke Xiaobaiyue Race 53 A-E
Android Studio 实现登录注册-源代码 (连接MySql数据库)
Mysql8创建用户以及赋权操作
8 ways to get element attributes in JS
这本记述40年前历史的游戏书,预言的却是当下的事
【元胞自动机】基于元胞自动机模拟生命演化、病毒感染等实例附matlab代码
随机推荐
ENS emoji domain name is on fire!Hype or opportunity?
[Nuxt 3] (十四) Nuxt 生命周期
awk notes
关于MySQL主从复制的数据同步延迟问题
[Machine Learning] The Beauty of Mathematics Behind Gradient Descent
7.联合索引(最左前缀原则)
【元胞自动机】基于元胞自动机模拟生命演化、病毒感染等实例附matlab代码
软考 --- 数据库(6)数据仓库、分布式数据库
bgp路由过滤
Swift RegexBuilder Vs. Raku Grammar
数字货币期货现货交易技巧,把握关键进场的买入点!(纯干货)
[Deep Learning] Understanding of Domain Adaptation in Transfer Learning and Introduction of 3 Techniques
GPGGA NTRIP RTCM 笔记
Redis数据更新,是先更新数据库还是先更新缓存?
你需要知道的ES6—ES13开发技巧
JS中获取元素属性的8大方法
MySQL60 homework
Automatically generate test modules using JUnit4 and JUnitGenerator V2.0 in IDEA
[Deep Learning] Target Detection | SSD Principle and Implementation
手把手教你搭建一台永久运行的个人服务器