Go 学习笔记——函数篇一
先自嘲
转眼有 20 多天过去了,终于又来写东西了。。不知道是上了年纪还是还没从近期加班的焦虑中摆脱出来,再加上前阵子封控在家办公,最近总是禁不住的犯懒,代码也不想好好写,能复制粘贴就绝不动脑子,说到写博客也是,又要看TonyBai老师的课,还要在自己的环境上试一下,然后在总结沉淀,这一套流程下来,我感觉我的脑子都不够用了~~
但也正是因为年纪大了,所以认识也就成熟了点,这种状态,可不能让它形成常态,还是得需要做点什么来打破这个状态。
虽然近期项目也很紧张,但大多是些无聊透顶的业务编码,提不起兴致,前阵子本来还想自己写一个有趣的控制台工具,用来做一些自动化运维之类的工作,但也是写到一半就停工了,主要还是因为项目时间紧,没办法集中起来,所以还是厚着脸来博客更博吧。为什么说厚着脸,因为距离上篇实在太久了,5 月份的 21 天活动我也凑不够了,而且,我实在是想换换口味,先写点别的然后在继续 Go 的学习笔记,但又颓了这么久,一时间也不知道写啥~~~ ̄□ ̄||
言归正传
好了,还是继续记笔记吧。对了,再提一句,现在互联网行业不景气,贸然的把主要语言技能转到别的语言有一定风险,但 Go,Python 等这类语言不一样,他们本身的特色就是容易上手,加上社区比较成熟热闹,我个人还是建议多了解一下,先作为辅助技能傍身,后期看情况随时可以扶正上位!而且,在了解一门新的语言的同时,可以接触到相关的生态环境,比如容器编排啊,比如某个新的微服务框架啊(微软新出的 dapr 不就是 go 开发的),再比如 Python 现在作为很多机器学习,大数据相关的接口对接语言,可以借机了解很多语言之外的知识,虽是蜻蜓点水,但也能积少成多,聚沙成塔。
函数概念
在 Go 语言中,函数是唯一一种基于特定输入,实现特定任务并可返回任务执行结果的代码块
Go 函数与函数声明
一个 Go 函数的声明由五部分组成
第一部分是关键字 func,Go 函数声明必须以关键字 func 开始。
第二部分是函数名。函数名是指代函数定义的标识符
ps.函数名应该是唯一的,并且它也遵守 Go 标识符的导出规则,也就是首字母大写的函数名指代的函数是可以在包外使用的,小写的就只在包内可见。
第三部分是参数列表。参数列表中声明了我们将要在函数体中使用的各个参数。
ps.Go 函数支持变长参数,也就是一个形式参数可以对应数量不定的实际参数
第四部分是返回值列表。返回值承载了函数执行后要返回给调用者的结果,返回值列表声明了这些返回值的类型,返回值列表的位置紧接在参数列表后面,两者之间用一个空格隔开。
ps.上图 go 标准库里的 Fprintf 函数除了声明了返回值类型,还声明了返回值名称,这种返回值被称为“具名返回值”,这并不常见。
第五部分是放在一对大括号内的是函数体,函数的具体实现都放在这里。
ps.注意,函数生命中的函数体是可选的。
特点
由这个图的可知,
函数声明中的函数名其实就是变量名,函数声明中的 func 关键字、参数列表和返回值列表共同构成了函数类型。
参数列表与返回值列表的组合也被称为函数签名,它是决定两个函数类型是否相同的决定因素。
通常,在表述函数类型时,我们会省略函数签名参数列表中的参数名,以及返回值列表中的返回值变量名,比如上图的 Fprintf 函数的函数类型是
注意,函数签名(参数列表和返回值列表)是决定两个函数类型是否相同的因素,也就是即便参数名和返回值变量名不一样,他们也是同类型的函数类型!
上面两个函数把参数名和变量名省掉后,就是都是 func (int, string) ([]string, error)类型,也就是相同的函数类型。
每个函数声明所定义的函数,仅仅是对应的函数类型的一个实例,就像 var a int = 13 这个变量声明语句中 a 是 int 类型的一个实例一样
函数的参数
函数声明阶段,参数列表中的参数叫形参,被调用是传入的参数是实参,这个应该不用多说了吧~
参数传递
函数传递参数采用的是值传递的方式。
关于值传递,基本有两种拷贝形式;
一种是“逐位拷贝”,对于像整型、数组、结构体这类类型,它们的内存表示就是它们自身的数据内容,因此当这些类型作为实参类型时,值传递拷贝的就是它们自身,传递的开销也与它们自身的大小成正比。
一种是“浅拷贝”,像 string、切片、map 这些类型,它们的内存表示对应的是它们数据内容的“描述符”。当这些类型作为实参类型时,值传递拷贝的也是它们数据内容的“描述符”,不包括数据内容本身,所以这些类型传递的开销是固定的,与数据内容大小无关。
例外形式:形参为接口类型和变长参数时,简单的值传递就不在满足需求,Go 编译器会介入:对于类型为接口类型的形参,Go 编译器会把传递的实参赋值给对应的接口类型形参;对于为变长参数的形参,Go 编译器会将零个或多个实参按一定形式转换为对应的变长形参。
函数返回值
Go 函数支持多返回值
函数返回值还可以为每个返回值声明变量名,像开头 go 标准库里的 Fprintf 函数,这类带名字的返回值被称为“具名返回值”。
函数是“一等公民”
“如果一门编程语言对某种语言元素的创建和使用没有限制,我们可以像对待值(value)一样对待这种语法元素,那么我们就称这种语法元素是这门编程语言的“一等公民”。拥有“一等公民”待遇的语法元素可以存储在变量中,可以作为参数传递给函数,可以在函数内部创建并可以作为返回值从函数返回。”
特征一:Go 函数可以存储在变量中。
特征二:支持在函数内创建并通过返回值返回。
Go 函数不仅可以在函数外创建,还可以在函数内创建。而且由于函数可以存储在变量中,所以函数也可以在创建后,作为函数返回值返回。
下面这个例子可能有点绕,截个图后续帮助了解一下
在列举一个利用闭包简化函数调用的案例
特征三:作为参数传入函数。
特征四:拥有自己的类型。
关于函数的概念,我就不过多记录了,大家有了解需求的话,可以还是去看一下TonyBai老师的课,这节偏概念性的东西还是多一些,比较干,所以能总结的东西也就少了,主要是梳理了一下知识点。
版权声明: 本文为 InfoQ 作者【为自己带盐】的原创文章。
原文链接:【http://xie.infoq.cn/article/92c93551212b5c1fe7f2e0658】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论