关键词:
函数声明和注释
1、函数声明: func 函数名字 (参数列表) [(返回值列表)] {}
func add(a, b int) (int, int) { }
2. 注释,两种注释,单行注释: // 和多行注释 /* */
3、 一个.go文件初始化,先执行全局变量,再执行init()函数,init()函数自动调用
4、多个包引用,如果引用顺序是main -> add -> test,初始化顺序:test.go的全局变量->test.go的init()->add全局变量->add.go的init()->main.go全局变量->main.go的init()
函数特点
- 不支持重载,一个包不能有两个名字一样的函数
- 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
- 匿名函数
- 多返回值
样例:
package main import "fmt" type op_func func(int, int) int func add(a, b int) int { return a + b } func sub(a, b int) int { return a - b } func operator(op op_func, a int, b int) int { return op(a, b) } func main() { c := add fmt.Println(c) sum := operator(c, 100, 200) fmt.Println(sum) var d op_func d = sub fmt.Println(d) sub := operator(d, 100, 200) fmt.Println(sub) }
自定义函数
demo
package main import "fmt" type add_func func(int, int) int func add(a, b int) int { return a + b } func operator(op add_func, a int, b int) int { //使⽤用传进来的函数,进⾏行行操作 return op(a, b) } func main() { c := add fmt.Println(c) sum := operator(c, 100, 200) fmt.Println(sum) }
函数参数传递方式
- 值传递
- 引用传递
注意:无论是值传递,还是引用传递,传递给函数的都是变量的副本。不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。
map、slice、chan、指针、interface默认以引用的方式传递。
命名返回值的名字
func add(a, b int) (c int) { c = a + b return } func calc(a, b int) (sum int, avg int) { sum = a + b avg = (a + b)/2 return }
_标识符,用来忽略返回值
func calc(a, b int) (sum int, avg int) { sum = a + b avg = (a + b) / 2 return } func main() { sum, _ := calc(100, 200) }
可变参数
- 0个或多个参数
func add(arg…int) int { }
- 1个或多个参数
func add(a int, arg…int) int { }
- 2个或多个参数
func add(a int, b int, arg…int) int { }
注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数。
样例:
package main import "fmt" func add(a int, arg...int) int{ var sum int = a for i := 0; i < len(arg); i ++ { sum += arg[i] } return sum } func add_string(a string, arg...string) (result string) { result = a for i := 0; i < len(arg); i ++ { result += arg[i] } return } func main() { sum := add(10, 1 , 2, 3) fmt.Println(sum) str := add_string("hello ", "world ", "wang") fmt.Println(str) }
匿名函数
样例:
package main import "fmt" var( result = func(a1, b1 int) int{ return a1 + b1 } ) func test(a, b int) int { result := func(a1, b1 int) int{ return a1 + b1 }(a, b) return result } func test1(a, b int) int { result := func(a1, b1 int) int{ return a1 + b1 } return result(a, b) } func main() { sum := test(10 , 20) fmt.Println(sum) sum1 := test1(1, 2) fmt.Println(sum1) fmt.Println(result(3,4)) }
defer用途
- 当函数返回时,执行defer语句。因此,可以用来做资源清理
- 多个defer语句,按先进后出的方式执行
- defer语句中的变量,在defer声明时就决定了
样例:
package main import "fmt" func main() { var i int = 0 defer fmt.Println(i) defer fmt.Println("second") i = 10 fmt.Println(i) }
说明:上面代码执行,先将defer压入栈中,当main函数执行完成后,再执行defer内容。多个defer语句,按先进后出的方式执行。同时defer语句的变量i声明时为0,所以结果也为0
使用场景举例:
1、关闭文件句柄
func read() { //文件操作 file := open(filename) defer file.Close() }
2、锁资源释放
func read() { mc.Lock() defer mc.Unlock() // 其他操作 }
3、数据库连接释放
func read() { conn := openDatabase() defer conn.Close() //其他操作 }
内置函数
- close:主要用来关闭channel
- len:用来求长度,比如string、array、slice、map、channel
- new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
- make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
- append:用来追加元素到数组、slice中
- panic和recover:用来做错误处理
new和make的区别
package main import "fmt" func test() { s1 := new([]int) fmt.Println(s1) s2 := make([]int, 10) fmt.Println(s2) *s1 = make([]int, 5) (*s1)[0] = 100 s2[0] = 100 fmt.Println(s1) return } func main() { test() }
递归函数
函数调用自己,就叫做递归。
递归的设计原则
- 一个大的问题能够分解成相似的小问题
- 定义好出口条件
样例:
package main import ( "fmt" "time" ) func recusive(n int) { fmt.Println("hello", n) time.Sleep(time.Second) if n > 10 { return } recusive(n + 1) } func factor(n int) int { if n == 1 { return 1 } return factor(n-1) * n } func fab(n int) int { if n <= 1 { return 1 } return fab(n-1) + fab(n-2) } func main() { //fmt.Println(factor(5)) recusive(0) /*for i := 0; i < 10; i++ { fmt.Println(fab(i)) }*/ }
闭包
一个函数和与其相关的引⽤用环境组合⽽而成的实体。
demo1:
func Adder() func(int) int { var x int f := func(i int) int { x = x + i return x } return f } func testClosure() { f1 := Adder() fmt.Println(f1(10)) fmt.Println(f1(20)) fmt.Println(f1(30)) f2 := Adder() fmt.Println(f2(10)) fmt.Println(f2(20)) fmt.Println(f2(30)) }
demo2:
package main import ( "fmt" "strings" ) func makeSuffixFunc(suffix string) func(string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { return name + suffix } return name } } func main() { bmp := makeSuffixFunc(".bmp") jpg := makeSuffixFunc(".jpg") fmt.Println(bmp("test")) fmt.Println(jpg("test")) }
go函数
函数声明和注释1、函数声明:func函数名字(参数列表)(返回值列表){}2.注释,两种注释,单行注释://和多行注释/**/3、一个.go文件初始化,先执行全局变量,再执行init()函数,init()函数自动调用4、多个包引用,如果引用顺序是mai... 查看详情
go语言学习(二十)go语言递归函数
Go语言递归函数递归,就是在运行的过程中调用自己。语法格式如下:funcrecursion()recursion()/*函数调用自身*/funcmain()recursion()Go语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。递归函... 查看详情
go语言之函数方法
在Go语言中,函数和方法不太一样,有明确的概念区分。在其他语言中,比如Java,一般来说,函数就是方法,方法就是函数。但是在Go语言中,函数是指不属于任何结构体、类型的方法。也就是说,函数是没有接收者的;而方法... 查看详情
go语言学习笔记—基础—函数:函数声明(代码片段)
go函数特点函数是模块化、可复用、用于实现单一或相关联功能的代码块,用于执行一个任务。go函数具有以下特点:go工程至少有一个main()函数go语言通过函数来划分不同逻辑功能,每个函数执行指定任务go语言标准... 查看详情
5.go函数
【定义函数】直接上一个栗子,Go语言定义函数:funcadd(aint,bint)intreturna+b一目了然,还不太习惯Go语言的命名方式,类型为什么要写到后面?【多个返回值】Go函数还可以返回多个值:funcadd(aint,bint)(int,int)returna,a+b【命名返回值】f... 查看详情
go语言函数(代码片段)
函数Go语言和C语言一样也有函数的概念,Go语言中函数除了定义格式和不用声明以外,其它方面几乎和C语言一模一样格式:func函数名称(形参列表)(返回值列表)函数体;无参数无返回值函数funcsay() fmt.Println("HelloWorld!!!")有参数无... 查看详情
go函数参数
函数参数类型为:整数类型函数参数类型为:数组类型 查看详情
一文熟悉go函数
...狂热。哈喽大家好,我是陈明勇,今天分享的知识是Go的函数。如果本文对你有帮助,不妨点个赞,如果你是Go语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!函数函数的英文单词是Funct... 查看详情
go常用函数
1.字符串函数 查看详情
go语言|02for循环及常用函数的使用(代码片段)
文章目录前言for&range函数for语法for使用range遍历for循环嵌套breakmake&map函数make(集合)map(范围)delete()函数Go语言函数函数定义函数调用函数返回多个值Go语言函数值传递值Go语言函数引用传递值Go语言函数作... 查看详情
go语言|02for循环及常用函数的使用(代码片段)
文章目录前言for&range函数for语法for使用range遍历for循环嵌套breakmake&map函数make(集合)map(范围)delete()函数Go语言函数函数定义函数调用函数返回多个值Go语言函数值传递值Go语言函数引用传递值Go语言函数作... 查看详情
godefer(go延迟函数)
godefer(go延迟函数)Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此。根据GOLANGUAGESPEC的说法:A"defer"statementinvokesafunctionwhoseexecutionisdeferredtothemomentthesurroundingfunctionreturns,eitherbecausethesurroundingfunc 查看详情
go语言递归函数
Go语言递归函数递归,就是在运行的过程中调用自己。语法格式如下:1funcrecursion(){2recursion()/*函数调用自身*/3}45funcmain(){6recursion()7}Go语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。... 查看详情
go语言学习之旅--函数(代码片段)
函数GoLang函数介绍Go语言中函数特性函数的定义匿名函数闭包deferinit函数GoLang函数介绍函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型... 查看详情
go-函数
定义语法-func函数名(参数列表)(返回值列表){}packagemainimport("fmt")funcmyfunc(a,bint)(r1,r2int){r1=a+br2=a-breturn}funcmain(){r1,r2:=myfunc(5,1)fmt.Println(r1)fmt.Println(r2)}//output64 匿名函数Go 语言允许将函数传递给一个变 查看详情
[golang]go中函数和方法的区分(代码片段)
说明在很多的语言当中,函数就是方法,例如Java。但是在go语言当中,函数和方法不太一样,有明确的概念区分。go中,函数是指不属于任何结构体、类型的方法,也就是说,函数是没有接收者的;而方法有接收者。我们在go中... 查看详情
go语言函数语法下篇(代码片段)
...录一、延迟执行语句defer1.1defer概念1.2使用演示二、递归函数三、Go语言处理运行时错误3.1错误处理思想3.2错误接口的定义四、Go语言宕机五、Go语言宕机恢复recover5.1基础概念5.2让程序在崩溃时继续执行5.3panic和recover的关系六、计... 查看详情
1.4go微服务实战(go语言基础)---函数方法接口和反射
第4章 函数、方法、接口和反射4.1 函数 4.1.1 函数的定义 4.1.2 闭包 Go语言中的闭包就是引用了自由变量的函数,被引用的自由变量同函数一直存在,即时离开了自由变量的环境也不会被释放和删除。闭包中可以 继... 查看详情