golang:函数总结
golang保留的函数
init(), main()是golang的保留函数,有如下特点:
main()只能用在main包中,仅可定义一个,init()可定义任意包,可重复定义,建议只定义一个- 两个函数定义时不能有任何返回值
- 只能由go自动调用,不可被引用
init()先于main()执行,并不能被其他函数调用,执行时按照main import顺序执行。
包的执行顺序
- Go的初始化和执行总是从main.main函数(main包导入其它的包)
- 同包下的不同
.go文件,按照以文件名或包路径名的字符串顺序“从小到大”排序顺序执行 - 其他的包只有被
main包 import 才会执行,按照 import 的先后顺序执行; - 如果某个包被多次导入的话,在执行的时候只会导入一次;
- 当一个包被导入时,如果它还导入了其它的包,则先将其它的包包含进来;
- 导入顺序与初始化顺序相反 main => p1 => p2 | p2 => p1 => p
- main被最后一个初始化,因其总是依赖其他包
函数
函数是将具有独立功能的代码组织成为一个整体,使其具有特殊功能的代码集。在Go语言中,函数是一种数据类型,其特性有如下:
- 支持匿名函数
- 支持带有变量名的返回值
- 支持多值返回
- 支持匿名函数
- 不支持重载,一个包中不能有两个名字一样的函数。
定义语法
func test(){
}
func test(a int, b int){
}
func test(a,b int){
}
func test(a,b int list...int){
}
func test(a int, b int) int{
}
func test(a int, b int ) (int,int){
}
func test(a,b int) (num int, err error){
}
花括号必须与函数声明在同一行,这种写法是错误的
func test()
{
}
命名返回值名称
package main
import "fmt"
func test(a, b, c int) (he int, cha int) {
he = a + b + c
cha = a - b - c
return
}
func main() {
a, b := test(15, 10, 5)
fmt.Println(a)
fmt.Println(b)
}

_标识符,用来忽略返回值
函数参数传递方式
\1. 值传递
\2. 引用传递
注意:无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的持贝。引用传递是地址的持贝,一般来说,地址持贝更为高效。而值持贝取决于拷贝的对象大小,对象越大,则性能越低。
注意2:map、slice、chan、指针、interface默认以引用的方式传递
自定义函数类型
package main
import "fmt"
type ty_func func(int, int) int
func add(a, b int) int {
return a + b
}
func operator(op ty_func, a, b int) int {
return op(a, b)
}
func main() {
c := add
sum := operator(c, 100, 200)
fmt.Println(sum)
}

不定参数
- 不定参数可以通过下标/循环方式获取参数值
- 不定参数在定义时,固定参数放前面,不定参数放后面
- 在对函数调用时,固定参数必须传值,不定参数可以根据需要来决定是否要传值
语法
func {func_name}({param} ...{type}){
func_body
}
参数的类型是一个 {type} 类型的集合
练习:写一个函数add,支持1个或多个int相加,并返回相加结果
package main
import "fmt"
func test(num ...int) {
var sum int
for n := 1; n <= len(num); n++ {
sum += num[(n - 1)]
}
fmt.Println(sum)
}
func main() {
test(1)
test(1, 2, 3)
test(1, 2, 3, 4)
}

练习:写一个函数concat,支持1个或多个string相拼接,并返回结果
func concat(age ...string) {
var str string
for _,v := range age {
str += v
}
fmt.Println(str)
}
func main() {
concat("hellow", " world", " go")
}

延迟调用defer
- 当函数返回时,执行defer语句。因此,可以用来做资源清理
- 多个defer语句,按LIFO(后进先出)的顺序执行
- defer语句中的变量,在defer声明时就决定了。
用途
- 关闭文件句柄
- 锁资源释放
- 数据库连接释放
defer语句中的变量,在defer声明时就决定了其值
func defer_test() {
i := 0
defer fmt.Println(i)
i = 10
fmt.Println(i)
}
func main() {
defer_test()
}

多个defer按LIFO(后进先出)的顺序执行
func defer_test() {
i := 0
defer fmt.Println(i)
i = 10
fmt.Println(i)
}
func main() {
defer_test()
}

defer的作用域,此处可以看到,defer的传入不是在main的作用域下,测试可发现 defer只会在当前函数和方法返回之前被调用。
package main
import "fmt"
func main() {
fmt.Println("block starts")
{
defer fmt.Println("defer runs")
fmt.Println("block ends")
}
fmt.Println("main ends")
}

函数作用域
全局变量:既能在函数中使用,也能在其他函数中使用,可以称为定义在函数外的变量。
局部变量:定义在函数内部的变量成为局部变量,局部变量的作用域在函数内部。
如果全局变量的名字和局部变量的名字相同,使用的是局部变量
匿名函数
package main
import "fmt"
var (
test = func(a, b int) int {
return a + b
}(10, 20)
)
var test1 = func(age ...int) int {
var sum int
for n := 0; n < len(age); n++ {
sum += age[n]
}
return sum
}
func main() {
c := test
fmt.Println(c)
d := test1(100, 100, 100)
fmt.Println(d)
}

golang:函数总结的更多相关文章
- GO开发[四]:golang函数
函数 1.声明语法:func 函数名 (参数列表) [(返回值列表)] {} 2.golang函数特点: a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个 ...
- golang函数学习笔记
golang函数特点: a.不支持重载,一个包不能有两个名字一样的函数 b.函数是一等公民,函数也是一种类型,一个函数可以赋值给变量 c.匿名函数 d.多返回值 例子1 func add(a, b ...
- golang 函数作为类型
golang 函数作为类型 package main import "fmt" type A func(int, int) func (f A)Serve() { fmt.Prin ...
- electron/nodejs实现调用golang函数
https://www.jianshu.com/p/a3be0d206d4c 思路 golang 支持编译成c shared library, 也就是系统中常见的.so(windows下是dll)后缀 ...
- vim支持golang函数调整
golang函数跳转需要借助godef实现 godef安装如下 go get -v github.com/rogpeppe/godef go install -v github.com/rogpepp ...
- Golang函数-递归函数
Golang函数-递归函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Golang函数-不定参函数
Golang函数-不定参函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Golang函数-匿名函数与闭包函数
Golang函数-匿名函数与闭包函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Golang函数-函数的基本概念
Golang函数-函数的基本概念 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数的概述 1>.函数定义语法格式 Go语言函数定义格式如下: func 函数名( 函数参 ...
- golang 函数和方法
由于自己是搞python开发的,所以在学习go时,当看到函数和方法时,顿时还是挺蒙的,因为在python中并没有明显的区别,但是在go中却是两个完全不同的东西.在官方的解释中,方法是包含了接收者的函数 ...
随机推荐
- 【死磕JVM】给同事讲了一遍GC后,他要去面试,年轻人,就是容易冲动!
前言 在一个风和日丽的中午,和同事小勇一起走在公司楼下的小公园里面,看到很多的小姐姐,心想什么时候能够和这些小姐姐一起讨论人生呀,美滋滋,嘿嘿嘿. 收起你的哈喇子好不好,小勇总是在这个时候发出声音,挺 ...
- Mokito 单元测试与 Spring-Boot 集成测试
Mokito 单元测试与 Spring-Boot 集成测试 版本说明 Java:1.8 JUnit:5.x Mokito:3.x H2:1.4.200 spring-boot-starter-test ...
- Windows Server 2016不小心卸载了.NET Framwork4.6后服务器管理器等功能都不能用的解决方案
之前卸载IIS的时候手贱把.NET FrameWork 4.6给卸载了,下面有一个比较简单的恢复方法. 可以尝试一下通过cmd命令DISM启用.NET 4.6:1. 首先运行如下命令查看当前的功能安装 ...
- 【C/C++】memset方法的误区
目录 一.前言 二.函数作用 三.效率对比 四.误区总结 1.按字节设置 2.设置的值只有最低字节有效 3.堆内存不可直接 sizeof 取首地址 4.传参数组不可直接 sizeof 取首地址 一.前 ...
- OO_Unit4 UML模型化设计总结
OO_Unit4 UML模型化设计总结 任务简介:本单元在介绍了UML中几种基本的模型图元素的基础上,通过实现课程组提供的官方接口来完成自己的UML解析器. 架构设计 本单元最终的整体架构图如下(不包 ...
- [shell脚本]在Linux终端可视化输出表格数据
最终效果 1. 自定义表格样式 2. 自定义主题颜色 支持三系普通颜色 支持16色彩虹色 支持单颜色 回顾一下shell语法 1. shell传递参数 我们可以在执行shell脚本时实时传递参数从而指 ...
- 四两拨千斤——你不知道的VScode编码TypeScript的技巧
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文参考:https://blog.bitsrc 如果你体验过JAVA这种强类型语言带来的便利,包括其丰富的 ...
- php抽象类,接口,特性的比较
php抽象类 抽象方法必须被子类继承实现,所以不能为私有,只能是受保护的或公有的; 抽象类子类的方法访问控制级别必须和抽象类相等或更宽松.例如,父类的抽象方法是受保护的,子类实现时则必须为受保护的或者 ...
- 【接口设计】用户积分排行榜功能-Redis实现
一.排行榜功能简介 排行榜功能是一个很普遍的需求.使用 Redis 中有序集合(SortedSet)的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如交通数据流中的路口/路段的车流量 ...
- 缓冲区溢出分析第08课:MS06-040漏洞研究——动态调试
前言 经过上次的分析,我们已经知道了MS06-040漏洞的本质,那么这次我们就通过编程实现漏洞的利用. 编写漏洞利用程序的框架 这里我使用的是VC++6.0进行编写,需要将包含有漏洞的netapi32 ...