
go函数
函数定义
go
package main
import "fmt"
// 官方建议:最好命名返回值,因为不命名返回值,虽然使得代码更加简洁了,但是会造成生成的文档可读性差
func Test02() (value int) { //方式2, 给返回值命名
value = 250
return value
}
func Test03() (value int) { //方式3, 给返回值命名
value = 250
return
}
func main() {
value := Test02()
value2 := Test03()
fmt.Println(value, value2)
}
多个返回值
go
package main
import "fmt"
func Test01() (int, string) { //方式1
return 250, "sb"
}
func Test02() (a int, str string) { //方式2, 给返回值命名
a = 250
str = "sb"
return
}
// 求2个数的最小值和最大值
func MinAndMax(num1 int, num2 int) (min int, max int) {
if num1 > num2 { //如果num1 大于 num2
min = num2
max = num1
} else {
max = num2
min = num1
}
return
}
func main() {
v1, v2 := Test01() //函数调用
_, v3 := Test02() //函数调用, 第一个返回值丢弃
v4, _ := Test02() //函数调用, 第二个返回值丢弃
fmt.Printf("v1 = %d, v2 = %s, v3 = %s, v4 = %d\n", v1, v2, v3, v4)
minX, maxX := MinAndMax(33, 22)
fmt.Printf("min = %d, max = %d\n", minX, maxX) //min = 22, max = 33
}
函数类型
go
package main
import "fmt"
type FuncType func(int, int) int //声明一个函数类型, func后面没有函数名
// 函数中有一个参数类型为函数类型:f FuncType
func Calc(a, b int, f FuncType) (result int) {
result = f(a, b) //通过调用f()实现任务
return
}
func Add(a, b int) int {
return a + b
}
func Minus(a, b int) int {
return a - b
}
func main() {
//函数调用,第三个参数为函数名字,此函数的参数,返回值必须和FuncType类型一致
result := Calc(1, 1, Add)
fmt.Println(result) //2
var f FuncType = Minus
fmt.Println("result = ", f(10, 2)) //result = 8
}
匿名函数
go
package main
import "fmt"
func main() {
i := 0
str := "mike"
//方式1
f1 := func() { //匿名函数,无参无返回值
//引用到函数外的变量
fmt.Printf("方式1:i = %d, str = %s\n", i, str)
}
f1()
//匿名函数,有参有返回值
v := func(a, b int) (result int) {
result = a + b
return
}(1, 1)
fmt.Println("v = ", v)
}
闭包
简单的来说就是一个函数返回一个新的函数,就是闭包,并且里面定义的变量会在每次调用的时候生效,而不是重新初始化
go
package main
import "fmt"
// squares返回一个匿名函数,func() int
// 该匿名函数每次被调用时都会返回下一个数的平方。
func squares() func() int {
var x int
return func() int { //匿名函数
x++ //捕获外部变量
return x * x
}
}
func main() {
//闭包的使用
f := squares()
fmt.Println(f()) // "1"
fmt.Println(f()) // "4"
fmt.Println(f()) // "9"
fmt.Println(f()) // "16"
}
延迟调用defer
关键字 defer 用于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行。注意,defer语句只能出现在函数或方法的内部。 如果是多个defer的话,是先进后出的模式
go
package main
import "fmt"
func main() {
fmt.Println("this is a test")
defer fmt.Println("this is a defer") //main结束前调用
/*
运行结果:
this is a test
this is a defer
*/
}
如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行。哪怕函数或某个延迟调用发生错误,这些调用依旧会被执
go
package main
import "fmt"
func test(x int) {
fmt.Println(100 / x) //x为0时,产生异常
}
func main() {
defer fmt.Println("aaaaaaaa")
defer fmt.Println("bbbbbbbb")
defer test(0)
defer fmt.Println("cccccccc")
/**
结果: cccccccc
bbbbbbbb
aaaaaaaa
*/
}
如果报错的地方没有defer,那么就是加载那些就执行那些
go
package main
import "fmt"
func test(x int) {
fmt.Println(100 / x) //x为0时,产生异常
}
func main() {
defer fmt.Println("aaaaaaaa")
defer fmt.Println("bbbbbbbb")
test(0)
defer fmt.Println("cccccccc")
/**
结果:
bbbbbbbb
aaaaaaaa
*/
}
defer和匿名函数结合使用,注意,闭包函数如果传值的话则是传递的定义之前的值,一定要注意顺序
go
package main
import "fmt"
func test(x int) {
fmt.Println(100 / x) //x为0时,产生异常
}
func main() {
a, b := 10, 20
defer func(x int) { // a以值传递方式传给x
fmt.Println("defer:", x, b) // b 闭包引用
}(a)
a += 10
b += 100
fmt.Printf("a = %d, b = %d\n", a, b)
/*
运行结果:
a = 20, b = 120
defer: 10 120
*/
}
获取命令行参数
go run test.go 127.0.0.1 8080
, 注意 这个属于有三个参数,从0开始,第一个参数是test.go
go
package main
import "fmt"
import "os"
func test(x int) {
fmt.Println(100 / x) //x为0时,产生异常
}
func main() {
args := os.Args //获取用户输入的所有参数
//如果用户没有输入,或参数个数不够,则调用该函数提示用户
if args == nil || len(args) < 2 {
fmt.Println("err: xxx ip port")
return
}
ip := args[1] //获取输入的第一个参数
port := args[2] //获取输入的第二个参数
fmt.Printf("ip = %s, port = %s\n", ip, port) //ip = 127.0.0.1, port = 8080
}