golang学习笔记(五)函数
2022-11-13 本文已影响0人
NIIIICO
1、书写方式
package main
import "fmt"
func main() {
test1() // 1、无参
test2_1(1, 2) // 2、有参
test2_2(1, 2, 3) // 不定参 test2_2()
// 3、无参,单个返回值
fmt.Println("test3_1:", test3_1())
fmt.Println("test3_2:", test3_2())
fmt.Println("test3_3:", test3_3())
// 4、无参,多个返回值
a, b := test4_1()
fmt.Println("test4_1:", a, b)
a, b = test4_2()
fmt.Println("test4_2:", a, b)
a, b = test4_3()
fmt.Println("test4_3:", a, b)
// 5、有参,有返回值
max, min := test5(1, 2)
fmt.Println("test5:", max, min)
}
// 1、无参无返回值
func test1() {
fmt.Println("我是test1函数")
}
// 2.1、有参无返回值
func test2_1(a int, b int) {
fmt.Printf("我是test2_1函数:a=%d , b=%d\n", a, b)
}
// 2.2、不定参数,只能放在最后一个参数,不定参数可以不传
func test2_2(a ...int) {
for i, value := range a {
fmt.Printf("我是test2_2函数a[%d]=%d\n", i, value)
}
// 全部元素传递
// test2_3(a...)
// 传递部分元素,下标0-1的元素传递给下一个函数,含前不含后
// test2_3(a[:1]...)
// 传递部分元素,下标1-结束的元素传递给下一个函数
// test2_3(a[1:]...)
// 传递部分元素,下标1-2的元素传递给下一个函数,含前不含后
test2_3(a[1:2]...)
}
func test2_3(a ...int) {
for i, value := range a {
fmt.Printf("我是test2_3函数a[%d]=%d\n", i, value)
}
}
// 3.1、无参,只有一个返回值
func test3_1() int {
return 1
}
// 3.2、无参,只有一个返回值
func test3_2() (result int) {
return 1
}
// 3.3、无参,只有一个返回值
func test3_3() (result int) {
result = 1
fmt.Println("in test3_3")
return
}
// 4.1、无参,多个返回值
func test4_1() (int, int) {
return 1, 2
}
// 4.2、无参,多个返回值
func test4_2() (a int, b int) {
return 3, 4
}
// 4.3、无参,多个返回值
func test4_3() (a int, b int) {
a, b = 5, 6
fmt.Println("test4_3")
return
}
// 5、有参有返回值
func test5(a, b int) (max, min int) {
if a > b {
max = a
min = b
} else {
max = b
min = a
}
return
}
2、函数类型
函数类型也是一种数据类型,通过type起名
package main
import "fmt"
// 函数类型也是一种数据类型,通过type起名
type FuncType func(int, int) int
func main() {
// 声明一个函数类型的变量
var funcTest FuncType
// 给变量赋值
funcTest = add
fmt.Println("funcTest:", funcTest(1, 2))
// 重新赋值
funcTest = minus
fmt.Println("funcTest:", funcTest(1, 2))
}
func add(a, b int) int {
return a + b
}
func minus(a, b int) int {
return a - b
}
3、回调函数
回调函数:函数的参数是函数类型
package main
import "fmt"
// 函数类型也是一种数据类型,通过type起名
type FuncType func(int, int) int
func main() {
fmt.Println("calc的结果是:", calc(1, 2, minus))
}
// 回调函数,函数的参数是函数类型
func calc(a, b int, fTest FuncType) int {
return fTest(a, b)
}
func add(a, b int) int {
return a + b
}
func minus(a, b int) int {
return a - b
}
4、匿名函数
(1)匿名函数,没有函数名字
(2)后边跟()表示调用此匿名函数
package main
import "fmt"
func main() {
age := 18
name := "LiMing"
// 匿名函数,没有函数名字
f := func() {
fmt.Printf("匿名函数 name:%s, age:%d\n", name, age)
}
f()
// 后边的圆括号表示调用此匿名函数
func() {
fmt.Println("匿名函数")
}()
max, min := func(i, j int) (max, min int) {
if i > j {
max = i
min = j
} else {
max = j
min = i
}
return
}(10, 20)
fmt.Printf("max=%d, min=%d", max, min)
}
5、闭包
(1)闭包以引用方式捕获外部参数
(2)闭包不关心 捕获的变量 是否已经超出作用域,只要闭包还在使用它,这些变量就会存在
package main
import "fmt"
func main() {
age := 18
name := "LiMing"
// 闭包以引用方式捕获外部参数
func() {
fmt.Printf("匿名函数,初始值 name:%s, age:%d\n", name, age)
age = 19
name = "LiDaMing"
fmt.Printf("匿名函数,修改后的值 name:%s, age:%d\n", name, age)
}()
fmt.Printf(" name:%s, age:%d\n", name, age)
// 结果是 1,1,1
fmt.Println("test 结果:", test())
fmt.Println("test 结果:", test())
fmt.Println("test 结果:", test())
// 结果是 1,2,3
f := test2()
fmt.Println("test 结果:", f())
fmt.Println("test 结果:", f())
fmt.Println("test 结果:", f())
}
func test() int {
var x int
x++
return x
}
func test2() func() int {
var x int
// 闭包不关心 捕获 的变量是否已经超出作用域,只要闭包还在使用它,这些变量就会存在
return func() int {
x++
return x
}
}
6、defer
(1)延时,在函数结束前调用
(2)多个defer,后进先出 LIFO
(3)多个defer,如果某个函数发生错误,也可以都执行到
(4)崩溃代码不用defer修饰,后边的defer就不会执行
package main
import (
"fmt"
)
func main() {
// 延时,函数结束前调用
// 后进先出 LIFO
// 如果某个函数发生错误,也可以都执行到
// hello world !!!
// panic: runtime error: integer divide by zero
defer fmt.Print("!!! \n")
defer fmt.Print("world ")
defer test(0)
defer fmt.Print("hello ")
// world2 !!!2
defer fmt.Print("!!!2 \n")
defer fmt.Print("world2 ")
// 崩溃代码不用defer修饰,后边的defer就不会执行
test(0)
defer fmt.Print("hello2 ")
}
func test(a int) int {
return 100 / a
}
7、defer结合匿名函数
(1)不需要传参的函数,使用defer后,因为是后执行,捕获的是修改后的参数
(2)需要传参的函数,使用defer后,调用的时候已经传了值,只是延后调用
package main
import (
"fmt"
)
func main() {
// main a = 111 b = 222
// defer a = 111 b = 222
test()
// main a = 111 b = 222
// defer a = 10 b = 20
test1()
}
func test() {
a, b := 10, 20
defer func() {
fmt.Println("defer a = ", a, " b = ", b)
}()
a, b = 111, 222
fmt.Println("main a = ", a, " b = ", b)
}
func test1() {
a, b := 10, 20
defer func(a, b int) {
fmt.Println("defer a = ", a, " b = ", b)
}(a, b)
a, b = 111, 222
fmt.Println("main a = ", a, " b = ", b)
}
8、命令行参数
通过 os.Args 接收用户命令行传递的参数,以字符串传递
package main
import (
"fmt"
"os"
)
// 输出结果:
// length = 2
// value = C:\Users\zhaolin\AppData\Local\Temp\go-build1874253334\b001\exe\10.exe
// value = a
func main() {
// 通过 os.Args 接收用户命令行传递的参数,以字符串传递
list := os.Args
l := len(list)
fmt.Println("length = ", l)
for _, value := range list {
fmt.Println("value = ", value)
}
}