学习go语言编程之函数
函数定义
函数的基本组成:关键字func,函数名,参数列表,返回值,函数体,返回语句。
示例如下:
func Add(a int, b int) (ret int, err error) {
if a < 0 || b < 0 {
err = errors.New("should be non-negative numbers")
return
}
return a + b, nil // 支持多重返回值
}
如果参数列表中若干个相邻的参数类型相同,可以省略前面参数的类型声明:
// 参数列表中a,b的类型相同,省略了a参数的类型声明
func Add(a, b int) (ret int, err error) {
// ...
}
如果返回值列表中多个返回值的类型相同,也可以使用同样的方式合并。
如果函数返回值只有一个,不用声明返回值变量名:
// 函数只有一个返回值,不用声明返回值变量名
func Add2(a, b int) int {
// ...
}
函数调用
在调用函数前,需要导入函数所在的包:
import "mymath"// 假设Add被放在一个叫mymath的包中
c := mymath.Add(1, 2)
注意: Golang中函数名字的首字母大小写不仅仅是风格,更直接体现了该函数的可见性。
规则:小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其他包使用。这个规则也适用于类型和变量的可见性。
不定参数
不定参数是指函数的参数个数为不定数量。
不定参数类型
将函数定义为接收不定参数类型:
func myFunc(args ...int) {
for _, arg := range args {
fmt.Print(arg, " ")
}
fmt.Println()
}
调用:
// 传递给函数的参数个数不固定
myFunc(1)
myFunc(1, 2)
形如...type格式的类型只能作为函数的参数类型存在,并且必须是最后一个参数。
不定参数的传递
假设有一个变参函数myFun2:
func myFun2(args ...int) {
// ...
}
如下示例展示了如何向其传递变参:
func myFunc(args ...int) {
// 按原样传递
myFun2(args...)
// 传递参数片段
myFun2(args[1:]...)
}
任意类型的不定参数
如果希望传递任意类型的参数,可以指定类型为interface{}。
示例:
// 不定参数类型
func myPrintf(args ...interface{}) {
for _, arg := range args {
switch arg.(type) {
case int:
fmt.Println(arg, "is an integer")
case string:
fmt.Println(arg, "is a string")
case int64:
fmt.Println(arg, "is a int64")
default:
fmt.Println(arg, "is an unknown type")
}
}
}
func main() {
var v1 int = 1
var v2 int64 = 2
var v3 string = "hello"
var v4 float32 = 1.23
// 调用不定参数类型函数
myPrintf(v1, v2, v3, v4)
}
输出:
1 is an integer
2 is a int64
hello is a string
1.23 is an unknown type
多返回值
Golang函数或者成员的方法可以有多个返回值,这个特性能够使我们写出比其他语言更优雅、更简洁的代码。
比如File.Read()函数就可以同时返回读取的字节数和错误信息,如果读取文件成功,则返回值中的n为读取的字节数,err为nil,否则err为具体的出错信息:
func (file *File) Read(b []byte) (n int, err Error)
还可以给返回值命名,就像函数的输入参数一样。
返回值被命名之后,它们的值在函数开始的时候被自动初始化为空。
在函数中执行不带任何参数的return语句时,会返回对应的返回值变量的值。
Golang并不需要强制命名返回值,但是命名后的返回值可以让代码更清晰,可读性更强,同时也可以用于文档。
如果调用方调用了一个具有多返回值的方法,但是却不想关心其中的某个返回值,可以简单地用一个下划线“_”来跳过这个返回值。
比如下面的代码表示调用者在读文件的时候不想关心Read()函数返回的错误码:
n, _ := f.Read(buf)
匿名函数和闭包
匿名函数是指不需要定义函数名的一种函数实现方式。
匿名函数
在Golang中,函数可以像普通变量一样被传递或使用,可以随时在代码里定义匿名函数。
匿名函数由一个不带函数名的函数声明和函数体组成,如下所示:
func(a, b int, z float64) bool {
return a*b <int(z)
}
匿名函数可以直接赋值给一个变量或者直接执行:
// 定义匿名函数并赋值给变量
f := func(x, y int) int {
return x + y
}
// 调用函数
f(1, 2)
// 匿名函数的花括号后面直接跟参数列表表示调用匿名函数
func(x, y int) int {
return x + y
}(1,2)
闭包
Golang的匿名函数是一个闭包。
Golang中的闭包同样也会引用到函数外的变量,闭包的实现确保只要闭包还被使用,那么被闭包引用的变量会一直存在。
// 闭包
var j int = 5
a := func() {
var i int = 10
fmt.Printf("i, j: %d, %d\n", i, j)
}
a()
j *= 2
a() // 在这里还会调用闭包函数,被它引用的外部变量j一直存在,所以其只会在两次闭包调用时不同
输出:
i, j: 10, 5 # 第一次调用闭包函数时,变量j的值未变化
i, j: 10, 10 # 第二次调用闭包函数时,变量j的值已经发生变化
学习go语言编程之函数的更多相关文章
- 如何轻松学习C语言编程!
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- LINUX下C语言编程调用函数、链接头文件以及库文件
LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...
- 学习go语言编程系列之定义变量
package main import ( "fmt" "math") func main() { // 1. 定义变量名age,不初始化,使用对应类型的默认值 ...
- 学习go语言编程系列之helloworld
1. 下载https://golang.org/dl/ # Go语言官网地址,在国内下载太慢,甚至都无法访问.通过如下地址下载:https://golangtc.com/download. 2. 安装 ...
- C语言编程中函数指针的定义及使用
C语言中函数指针的定义: typedef int (*funcPtr)(int, int)表示定义了一个函数指针funcPtr,这个函数指针只能指向如下: int add(int, int).int ...
- c#基础语言编程-常用函数
类型转换Convert Convert考虑数据意义的转换. Convert是一个加工.改造的过程.在使用Convert的转换过程中不会返回异常,当遇到类型转换的不知道的时候,用Convert找找. T ...
- linux中c语言编程main函数和参数
linux下main函数的的标准调用函数的标准形式 int main(int char,char *argv[]) 在main函数的两个参数中,argc必须是整型变量,其是命令行的参数的数目,argv ...
- C语言编程漫谈——main函数
写在前面 促使我写这篇文章是因为我这几天找了几个一样是大三的同学,与我相同专业相同方向(物联网)的人,除了@小胡同的诗,基本没有什么其他人会现在看起来很简单的编程题目了.问了一下其他同学,他们大部分都 ...
- Linux C语言编程学习笔记 (1)进程控制入门
想进行Linux系统开发已经很久了,一直没有付诸实践.今日终于开始学习Linux下的C语言编程,研究一天,终于大概弄明白了Linux系统进程管理的一些基本概念和编程方法,总结下来以方便大家学习和自己实 ...
- C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
随机推荐
- [转帖]Prometheus监控系统存储容量优化攻略,让你的数据安心保存!
云原生监控领域不可撼动,Prometheus 是不是就没缺点?显然不是. 一个软件如果什么问题都想解决,就会导致什么问题都解决不好.所以Prometheus 也存在不足,广受诟病的问题就是 单机存储不 ...
- [转帖]SQL Server超过了每行的最大字节数(8060)的原因和解决办法
一.现象 出现这种错误都发生在SQL语句建表时,错误提示: "警告: 已创建表 'XXXX,但其最大行大小(10438)超过了每行的最大字节数(8060).如果结果行长度超过 806 ...
- SPEC2006的学习与总结
SPEC2006的学习与总结 摘要 最近特别想进行一些性能验证工作. 所以研究了spec2006 然后想整理一下之前的内容. 想着将内容整理一下. 这次主要是抄别人的. 知识来源: https://b ...
- [转帖]Nginx性能优化详解
https://developer.aliyun.com/article/886146?spm=a2c6h.24874632.expert-profile.256.7c46cfe9h5DxWK 感觉文 ...
- [转帖]【JVM】类加载机制
什么是类的加载 将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产 ...
- 高性能MySQL实战(三):性能优化 | 京东物流技术团队
这篇主要介绍对慢 SQL 优化的一些手段,而在讲解具体的优化措施之前,我想先对 EXPLAIN 进行介绍,它是我们在分析查询时必要的操作,理解了它输出结果的内容更有利于我们优化 SQL.为了方便大家的 ...
- TypeScript中typeof的简单介绍
简单介绍typeof 我们都知道js提供了typeof,用来获取基本数据的类型. 实际上,TS也提供了 typeof 操作符. 可以在 [类型上下文]中进行类型查询. 只能够进行变量或者属性查询. 定 ...
- RabbitMQ原理详解
RabbitMQ:我们通常谈到消息队列,就会联想到这其中的三者:生产者.消费者和消息队列,生产者将消息发送到消息队列,消费者从消息队列中获取消息进行处理.对于RabbitMQ,它在此基础上做了一层抽象 ...
- 东吴名贤传<一>骆统传
骆俊,字孝远,会稽郡乌伤县人(今义乌市),少有才干,察孝廉,补尚书郎,擢拜陈相,为东汉末年陈王刘宠的国相,时袁术僭号,兄弟忿争,天下鼎沸,群贼并起,陈与比界,奸慝四布,俊厉威武,保疆境,贼不敢犯.养济 ...
- FOG Project的 FOS 编译
FOG Project系统是一个免费的开源计算机网络克隆和管理解决方案系统,与传统的Ghost有很大的不同,如果您是计算机维护管理人员,当有大量机器需要同时部署上线的时候FOG Project是一个可 ...