Skip to content
鼓励作者:欢迎打赏犒劳

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
}

如有转载或 CV 的请标注本站原文地址