一、函数
1.不定参数函数(直接来难的)
package main
import "fmt"
func MyFunc() {
fmt.Println("无参数无返回值的函数")
}
func MyFunc01(a, b int) {
fmt.Printf("含有两个参数a = %d, b = %d\n", a, b)
}
//不定参数放在其他参数的最后,不定参数可以根据情况进行传递
func MyFunc02(args ... int) {
fmt.Println("参数长度:", len(args))
for a := 0; a < len(args); a++ {
fmt.Printf("arg[%d] = %d\n", a, args[a])
}
//迭代
for i, data := range args {
fmt.Printf("arg[%d] = %d\n", i, data)
}
}
func main() {
MyFunc()
MyFunc01(88, 99)
MyFunc02(1, 2, 3, 4)
}
无参数无返回值的函数
含有两个参数a = 88, b = 99
参数长度: 4
arg[0] = 1
arg[1] = 2
arg[2] = 3
arg[3] = 4
arg[0] = 1
arg[1] = 2
arg[2] = 3
arg[3] = 4
2.参数传递
package main
import "fmt"
func myfunc(tmp ...int) {
for _, data := range tmp {
fmt.Println("data = ", data)
}
}
func test(args ...int) {
//传递所有的参数给myfunc
myfunc(args[:]...)
fmt.Println("-----------------")
myfunc(args[:2]...)
fmt.Println("-----------------")
myfunc(args[2:]...)
}
func main() {
test(1, 2, 3, 4)
}
data = 1
data = 2
data = 3
data = 4
-----------------
data = 1
data = 2
-----------------
data = 3
data = 4
3.有返回值的函数
package main
import "fmt"
func myfunc01() int {
return 666
}
func myfunc02() (result int) {
return 777
}
func myfunc03() (result int) {
result = 888
return
}
func main() {
var a int
a = myfunc01()
fmt.Println("a = ", a)
a =myfunc02()
fmt.Println("a = ", a)
a =myfunc03()
fmt.Println("a = ", a)
}
4.函数有多返回值
package main
import "fmt"
func myfunc01() (int, int, int) {
return 1, 2, 3
}
//go推荐写法
func myfunc02() (a, b, c int) {
a, b, c = 111, 222, 333
return
}
func main() {
a, b, c := myfunc02()
fmt.Printf("a = %d, b = %d , c = %d\n", a, b, c)
}
a = 111, b = 222 , c = 333
5.注意事项
a.函数名字小写为private 大写即为public
b.不支持默认参数
c.如果没有返回值,就直接省略最后的返回信息
d.如果只有一个值且不声明返回值变量,则可以省略
e.函数的形参只是声明了两个变量类型,这样也可以
6.有参数有返回值
package main
import "fmt"
func MaxAndMin(a, b int) (max, min int) {
if (a > b) {
max = a
min = b
} else {
max = b
min = a
}
return
}
func main() {
max, min := MaxAndMin(10, 20)
fmt.Printf("max = %d , min = %d\n", max, min)
//匿名变量丢弃某个值
a, _ := MaxAndMin(10, 20)
fmt.Printf("a = %d\n", a)
}
max = 20 , min = 10
a = 20
7.递归
package main
import "fmt"
func tests(i int) int {
if i == 1 {
return 1
}
return i + tests(i-1)
}
func main() {
var sum int
sum = tests(100)
fmt.Printf("sum = %d\n", sum)
}
sum = 5050
8.函数类型
package main
import "fmt"
func Add(a, b int) int {
return a + b
}
func Minus(a, b int) int {
return a - b
}
//函数类型
type FuncType func(int, int) int
func main() {
//普通调用
var result int
result = Add(1, 2)
fmt.Printf("result = %d\n", result)
var ftype FuncType
ftype = Add
result = ftype(10, 20)
fmt.Printf("result2 = %d\n", result)
var ftype01 FuncType
ftype01 = Minus
result = ftype01(10, 20)
fmt.Printf("result3 = %d\n", result)
}
result = 3
result2 = 30
result3 = -10
9.回调函数
package main
import "fmt"
type FuncType01 func(int, int) int
func Add01(a, b int) int {
return a + b
}
func Minus01(a, b int) int {
return a - b
}
//函数有一个参数是函数类型,这个函数就是回调函数
func Calc(a, b int, fTest FuncType01) (result int) {
fmt.Printf("Calc")
result = fTest(a, b)
return
}
func main() {
a := Calc(1, 1, Add01)
fmt.Printf("a = %d\n", a)
b := Calc(1, 1, Minus01)
fmt.Printf("b = %d\n", b)
}
Calca = 2
Calcb = 0
10.匿名函数
package main
import "fmt"
func main() {
a := 10
str := "mike"
//匿名函数没有函数名字
f1 := func() {
fmt.Println("a =", a)
fmt.Println("str =", str)
}
f1()
fmt.Println("------------")
//起别名
type FuncType02 func()
var f2 FuncType02
f2 = f1
f2()
fmt.Println("------------")
//定义匿名函数,同时调用
func() {
fmt.Printf("a = %d, str = %s\n", a, str)
}()
fmt.Println("------------")
//定义匿名函数,有参数有返回值
x, y := func(i, j int) (max, min int) {
if i > j {
max = i
min = j
} else {
max = j
min = i
}
return
}(10, 20)
fmt.Printf("x = %d, y = %d\n", x, y)
}
a = 10
str = mike
------------
a = 10
str = mike
------------
a = 10, str = mike
------------
x = 20, y = 10
11.闭包
package main
import "fmt"
func main() {
a := 10
str := "hello"
func() {
//闭包以引用方式捕获外部变量
a = 999
str = "go"
fmt.Printf("内部 a = %d, str = %s\n", a, str)
}()
fmt.Printf("外部 a = %d, str = %s\n", a, str)
}
内部 a = 999, str = go
外部 a = 999, str = go
12.闭包的特点
package main
import "fmt"
//返回是一个匿名函数,返回一个函数类型
func fun() func() int {
var x int
return func() int {
x++
return x * x
}
}
func main() {
//特点:
//它不关心这些捕获了的变量和常量是否已经超出了作用域
//所以只有闭包还在使用它,这些变量就还会存在
f := fun()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
1
4
9
16
25
12.defer的延迟调用
defer fmt.Println("11111111111111")
fmt.Println("22222222222222")
22222222222222
11111111111111
13.多个defer的调用顺序
package main
import "fmt"
func fun(x int) {
result := 100 / x
fmt.Println("resut =", result)
}
func main() {
defer fmt.Println("11111111111111")
defer fmt.Println("22222222222222")
defer fun(0)
defer fmt.Println("3333333333333")
}
3333333333333
22222222222222
11111111111111
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.fun(0x0)
/Users/xxx/GOLang/demo01/02/09.go:7 +0xe4
main.main()
/Users/xxx/GOLang/demo01/02/09.go:19 +0x179
14.defer和匿名函数的混合使用
package main
import "fmt"
func main() {
a := 10
b := 20
defer func() {
fmt.Printf("a = %d, b = %d\n", a, b)
}()
a = 111
b = 333
fmt.Printf("外部的:a = %d, b = %d\n", a, b)
}
外部的:a = 111, b = 333
a = 111, b = 333
和下面的区别
package main
import "fmt"
func main() {
a := 10
b := 20
defer func(a, b int) {
fmt.Printf("a = %d, b = %d\n", a, b)
}(a, b)
a = 111
b = 333
fmt.Printf("外部的:a = %d, b = %d\n", a, b)
}
外部的:a = 111, b = 333
a = 10, b = 20