学习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语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
随机推荐
- [转帖]Linux的tmpfs和ramfs
tmpfs tmpfs是一种虚拟内存文件系统, 它的存储空间在VM里面,现在大多数操作系统都采用了虚拟内存管理机制, VM(Virtual Memory) 是由Linux内核里面的VM子系统管理. V ...
- [转帖]Kafka之ack机制
前言 之前的博客里说了,Kafka的消息同步是一种ISR机制,本质上是"完全同步"的一种优化. 都在说,消息被ISR中所有副本都写入才算写入成功.但是这样未免定的太死板了,所以,K ...
- [转帖]国产数据库到底行不行?人大金仓KINGBASE数据库与主流开源数据库性能实测
近年来,人大金仓的数据库产品受到了外界诸多的关注.做产品,免不了要接受用户的对比和选择,数据库因其行业的自身特点,还有很多开源的技术产品同台比拼,用户因此也会产生诸多疑问,国产数据库相比开源数据库到底 ...
- [转帖]ioping测试
https://www.cnblogs.com/ishmaelwanglin/p/10839702.html 一个实时显示磁盘io延时的工具,以类似ping 的输出一样展示输出结果 常用参数: -c ...
- vim配置的学习与总结
摘要 有时候在linux里面操作需要使用粘贴以及其他处理. 很多发行版, 遇到 # 会自动退格, 很难受. 想着能够处理一下vim的默认设置可以好很多. 所以这里简单总结一下. 配置文件 vim的配置 ...
- MySQL in Windows安装以及异名恢复的简单过程
下载相关 建议获取最新版本的Mysql数据库 可以获取 zip 格式的安装文件 https://dev.mysql.com/downloads/mysql/ 或者获取 msi 格式的安装文件 http ...
- js判断一个时间是否在某一个时间段内
很多时候,我们需要对时间进行处理: 比如说:获取当前的时间 判断某一个时间是否在一段时间内:如果在显示出某一个按钮: 让用户可以操作:如果不在,按钮隐藏 这个时候,我们就需要对时间进行处理了 < ...
- word文档删除空白页
记住两个快捷键 CTRL+Backspace Shift+Backspace 鼠标箭头放在空白的页面 按住键盘上的快捷键 就可以成功删除了不要天天看营销号设置什么磅值,全选删除啥的 效果如下
- Swift中发布-订阅框架Combine的使用
Combine简介 Combine是一个苹果用来处理事件的新的响应式框架,支持iOS 13及以上版本. 你可以使用Combine去统一和简化在处理类似于target-action,delegate,k ...
- Intel 14代酷睿提前上架加拿大:涨价最多7%
Intel将在10月17日正式发布14代酷睿,说白了就是13代酷睿升级版,代号就能说明一切--Raptor Lake Refresh. 首批发布的只是高端的K/KF系列,一共六款,分别是8+16 24 ...