上一篇文章
> Go入门(二)之基础类型、fmt格式化、运算符、流程控制
一、自定义函数
1、无参无返回值
package main
import "fmt"
// 无参无返回值的函数定义
func MyFunc() {
a := 123
fmt.Println("a = ", a)
}
func main() {
//函数调用
MyFunc()
}
结果:
a = 123
2、普通参数列表
(1)有参无返回值
package main
import "fmt"
// 有参无返回值的函数定义
func MyFunc(a int) {
fmt.Println("a = ", a)
}
func main() {
//函数调用
MyFunc(123)
}
结果:
a = 123
(2)不定参数列表
<1> 不定参数类型
package main
import "fmt"
func MyFunc(a int, args ...int) {
fmt.Println("a = ", a)
fmt.Println("长度等于", len(args))
fmt.Println("------------------------")
for i := 0; i < len(args); i++ {
fmt.Printf("args[%d] = %d\n", i, args[i])
}
fmt.Println("------------------------")
for i, data := range args {
fmt.Printf("args[%d] = %d\n", i, data)
}
}
func main() {
//函数调用
MyFunc(1, 2, 3)
}
结果:
a = 1
长度等于 2
------------------------
args[0] = 2
args[1] = 3
------------------------
args[0] = 2
args[1] = 3
<2> 不定参数传递
package main
import "fmt"
func MyFunc(tmp ...int) {
for _, data := range tmp {
fmt.Println("data = ", data)
}
}
func test(args ...int) {
// 全部元素传递给MyFunc
// MyFunc(args...)
//只想把后2个参数传递给另外一个函数使用
MyFunc(args[2:]...)
}
func main() {
test(1, 2, 3, 4)
}
结果:
data = 3
data = 4
3、无参有返回值
(1)一个返回值
package main
import "fmt"
// 无参数有一个返回值
func myfunc01() int {
return 123
}
// 给返回值起一个变量名,go推荐写法
func myfunc02() (result int) {
return 1234
}
// 常用写法
func myfunc03() (result int) {
result = 666
return
}
func main() {
fmt.Println("myfunc01 = ", myfunc01())
fmt.Println("myfunc02 = ", myfunc02())
fmt.Println("myfunc03 = ", myfunc03())
}
结果:
myfunc01 = 123
myfunc02 = 1234
myfunc03 = 666
(2)多个返回值
package main
import "fmt"
func myfunc01() (int, int, int) {
return 1, 2, 3
}
// go官网推荐写法
func myfunc02() (a int, b int, c int) {
a, b, c = 1, 2, 3
return
}
// 常用写法
func myfunc03() (a, b, c int) {
a, b, c = 1, 2, 3
return
}
func main() {
a, b, c := myfunc03()
fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
// myfunc01()
}
结果:
a = 1, b = 2, c = 3
4、有参有返回值
package main
import "fmt"
func MyFunc01(a, b int) (max, min int) {
if a > b {
max = a
min = b
} else {
max = b
min = a
}
return
}
func main() {
max, min := MyFunc01(10, 20)
fmt.Printf("max = %d, min = %d\n", max, min)
}
结果:
max = 20, min = 10
二、递归函数
package main
import "fmt"
// 实现1+2+3+100
// 方式一
func test01() (sum int) {
for i := 0; i <= 100; i++ {
sum += i
}
return
}
// 方式二
func test02(i int) int {
if i == 1 {
return 1
}
return i + test02(i-1)
}
// 方式三
func test03(i int) int {
if i == 100 {
return 100
}
return i + test02(i+1)
}
func main() {
// sum := test01()
// sum := test02(100)
sum := test03(100)
fmt.Println("sum = ", sum)
}
结果:
sum = 100
三、函数类型
1、类型
package main
import "fmt"
func Add(a, b int) int {
return a + b
}
func minus(a, b int) int {
return a - b
}
// 函数也是一种类型, 通过type给一个函数类型起名
// FuncType它是一个函数类型
type FuncType func(int, int) int // 没有函数名字,没有{}
func main() {
res := Add(1, 2)
fmt.Println("res = ", res)
// 声明一个函数类型的变量,变量名为fTest
var fTest FuncType
fTest = Add //是变量就可以赋值
res = fTest(10, 20)
fmt.Println("res1 = ", res)
fTest = minus
res = fTest(10, 2)
fmt.Println("res2 = ", res)
}
结果:
res = 3
res1 = 30
res2 = 8
2、回调函数
package main
import "fmt"
type FuncType func(int, int) int
// 实现加法
func Add(a, b int) int {
return a + b
}
func minus(a, b int) int {
return a - b
}
// 回调函数,函数有一个参数是函数类型
// 多态,多种形态
func Calc(a, b int, fTest FuncType) (result int) {
fmt.Println("Calc")
result = fTest(a, b)
return
}
func main() {
a := Calc(1, 1, Add)
fmt.Println("a = ", a)
b := Calc(2, 1, minus)
fmt.Println("b = ", b)
}
结果:
Calc
a = 2
Calc
b = 1
四、匿名函数与闭包
1、匿名函数
package main
import "fmt"
func main() {
a := 10
// 匿名函数
f1 := func() {
fmt.Println("a = ", a)
}
f1()
// 给函数起别名
type FuncType func()
// 声明变量
var f2 FuncType
f2 = f1
f2()
// 定义匿名函数,同时调用
func() {
fmt.Printf("a = %d\n", a)
}() //调用此匿名函数
// 带参数的匿名函数
f3 := func(i, j int) {
fmt.Printf("i = %d, j = %d\n", i, j)
}
f3(1, 2)
// 定义匿名函数,同时调用
func(i, j int) {
fmt.Printf("i = %d, j = %d\n", i, j)
}(10, 20)
// 匿名函数,有参有返回值
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("max = %d, min = %d\n", x, y)
}
结果:
a = 10
a = 10
a = 10
i = 1, j = 2
i = 10, j = 20
max = 20, min = 10
2、闭包
它不关心这些捕获了得变量和常量是否已经超出了作用域
所以只有闭包还在使用它,这些变量就会一直存在
package main
import "fmt"
func test01() int {
var x int
x++
return x * x //函数调用完毕就释放
}
// 闭包:函数返回值为一个匿名函数
func test02() func() int {
var x int
return func() int {
x++
return x * x
}
}
func main() {
fmt.Println(test01())
fmt.Println(test01())
fmt.Println(test01())
fmt.Println("-----------------")
f := test02()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
结果:
1
1
1
-----------------
1
4
9
五、延迟调用defer
1、defer使用
package main
import "fmt"
func main() {
// defer延迟调用,main函数结束前调用
defer fmt.Println("2222")
fmt.Println("1111")
}
结果:
1111
2222
2、多个defer的执行顺序
后进先出的顺序执行
package main
import "fmt"
func test(x int) {
fmt.Println(100 / x)
}
func main() {
defer fmt.Println("aaaa")
defer fmt.Println("bbbb")
defer test(0)
defer fmt.Println("ccc")
}
结果:
ccc
bbbb
aaaa
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.test(0x0)
E:/MyWork/Go Projects/src/wielun666@163.com/02/17_多个defer的执行顺序.go:6 +0xbb
main.main()
E:/MyWork/Go Projects/src/wielun666@163.com/02/17_多个defer的执行顺序.go:14 +0x193
exit status 2
3、defer和匿名函数结合使用
提前把参数传递进去了,只是没有进行调用
package main
import "fmt"
// func main() {
// a := 10
// defer func() {
// fmt.Println("a = ", a)
// }()
// a = 20
// fmt.Println("a = ", a)
// }
func main() {
a := 10
defer func(a int) {
fmt.Println("aaa = ", a)
}(a)
a = 20
fmt.Println("a = ", a)
}
结果:
a = 20
aaa = 10
六、获取命令行参数
package main
import (
"fmt"
"os"
)
func main() {
list := os.Args
n := len(list)
fmt.Println("n = ", n)
for i := 0; i < n; i++ {
fmt.Printf("list[%d] = %s\n", i, list[i])
}
fmt.Printf("-------------\n")
for i, data := range list {
fmt.Printf("range list[%d] = %s\n", i, data)
}
}
结果:
> go build .\19_获取命令行参数.go
> .\19_获取命令行参数.exe helo wielun
n = 3
list[0] = E:\MyWork\Go Projects\src\wielun666@163.com\02\19_获取命令行参数.exe
list[1] = hello
list[2] = wielun
-------------
range list[0] = E:\MyWork\Go Projects\src\wielun666@163.com\02\19_获取命令行参数.exe
range list[1] = hello
range list[2] = wielun
七、不用作用域同名变量
package main
import "fmt"
var a byte //全局变量
func main() {
var a int //局部变量
fmt.Printf("1: %T\n", a) //int
{
var a float32
fmt.Printf("2: %T\n", a) //float32
}
test()
}
func test() {
fmt.Printf("3: %T\n", a) //uint8,就是byte
}
结果:
1: int
2: float32
3: uint8
下一篇文章
> Go入门(四)之工程管理、复合类型