go语言---函数

函数就是一段具有特定功能的代码块
go语言中常用函数声明的格式:

func 函数名(参数列表) 返回值 {
	// 函数体
}

函数可以有参数,也可以没有参数,可以有返回值,也可以没有返回值;

go语言中的引用类型: slice map channel interface func();传递的是地址;
引用类型作为参数时,称为浅拷贝,形参改变,实参也跟随改变,因为传递的是地址,形参和实参都指向同一块地址;

理论上函数的返回值可以无限多个,但一般不会定义太多返回值的函数,后面会用结构体来代替多返回值;

匿名函数:
匿名函数不需要有函数名,一般都是在声明的地方直接调用;
因为没有名字,不方便在其他地方调用,调用即在函数声明的大括号后面紧跟一个小括号表示调用,中间可以有空格,但是不能有换行;
匿名函数都是声明在其他函数内部,不能定义在函数外部,因为没办法去调用它;匿名函数不调用编译报错;

函数变量:
在go语言中,函数也是一种类型,函数有多少中形式,函数变量就有多少种写法;
函数可以作为参数,也可以作为返回值;
在go语言中,函数也是一种类型,函数有多少中形式,函数变量就有多少种写法;
var a func()
var b func(int)
var c func(int) string
fmt.Println(a, b, c) // 指针类型,此时不会申请内存空间;
定义完函数变量后,可以使用匿名函数进行赋值,也可以使用已经定义好的函数进行赋值;
函数变量定义以后与普通函数调用语法相同,变量名就是普通函数声明的函数名;


package main

import "fmt"

func main() {
	noArgNoReturn()           // noArgNoReturn函数执行了
	hasAnArgNoReturn(999)     // 您输入的数字是:  999
	hasArgsNoReturn(666, 777) // 您输入的数字分别是:  666 777
	hasArgsHasReturn(12, 23)  // 35
	// 上面的函数有一个返回值,可以定义一个变量来接收
	sum := hasArgsHasReturn(11, 22)
	fmt.Println("返回的结果是: ", sum) // 两数相加的结果是:  33   返回的结果是:  33

	res := add(2, 3)
	fmt.Println("add(2, 3)计算的结果是: ", res) // add(2, 3)计算的结果是:  5

	// 接收多返回值, 要么不接收,要么就用与返回值数量相等的变量来接收, 如果某个返回值不需要使用,可以用下划线_来占位
	result, err := mutilReturn(1, 2)
	fmt.Println(result, err) // 3 Successful!

	r, _ := mutilReturn(3, 4)
	fmt.Println(r) // 7

	// 测试多个下划线接收
	x, _, _ := testLine()
	fmt.Println(x) // 测试下划线  1

	// 可变参数函数
	varArgs("张三", "上海", 22, "Programmer")
	/*
		张三的个人信息有:
		0 上海
		1 22
		2 Programmer
	*/

	// 匿名函数
	anonymousFunc()

	// 函数变量
	funcVariable()
}

func noArgNoReturn() {
	// 没有参数,没有返回值的函数
	fmt.Println("noArgNoReturn函数执行了")
}

func hasAnArgNoReturn(n int) {
	// 有1个参数, 没有返回值
	fmt.Println("您输入的数字是: ", n)
}

func hasArgsNoReturn(a, b int) {
	// 有两个参数,没有返回值
	fmt.Println("您输入的数字分别是: ", a, b)
}

func hasArgsHasReturn(a, b int) int {
	sum := a + b
	fmt.Println("两数相加的结果是: ", sum)
	return sum
}

// 上面的函数可以改写成
func add(a, b int) (sum int) {
	sum = a + b
	return // 这里的return不用写返回的内容是什么,因为在第一行已经定义了,返回值就是sum
}

// 多返回值函数, 多返回值函数的返回值可以不接收,但是如果要接收,就需要和返回值数量相等的变量去接收
func mutilReturn(a, b int) (res int, err string) {
	res = a + b
	err = "Successful!"
	return
}

// 测试能不能用多个下划线接收返回值
func testLine() (int, int, int) {
	fmt.Println("测试下划线")
	return 1, 2, 3
}

// 可变参数函数  可以将可变参数看做切片
func varArgs(name string, info ...interface{}) {
	fmt.Printf("%s的个人信息有:  \n", name)
	for i, n := range info {
		fmt.Println(i, n)
	}
}

// 匿名函数
func anonymousFunc() {
	// 无参匿名函数
	func() {
		fmt.Println("这是匿名函数")
	}() // 紧跟小括号表示调用  如果不调用编译报错: func literal evaluated but not used

	// 有参数的匿名函数
	func(s string) {
		fmt.Println("传入的参数是: ", s)
	}("参数xxx") // 传入的参数是:  参数xxx

	// 有参数有返回值的匿名函数
	r := func(s string) (res string) {
		fmt.Println("有参数有返回值的匿名函数")
		return "返回值"
	}("参数yyy")
	fmt.Println(r)
}

// 函数变量
/*
在go语言中,函数也是一种类型,函数有多少中形式,函数变量就有多少种写法
var a func()
var b func(int)
var c func(int) string
fmt.Println(a, b, c)   // <nil> <nil> <nil>  指针类型,此时不会申请内存空间
定义完函数变量后,可以使用匿名函数进行赋值,也可以使用已经定义好的函数进行赋值;
函数变量定义以后与普通函数调用语法相同,变量名就是普通函数声明的函数名;
*/
func funcVariable() {
	// 函数变量
	var a func()
	a = func() {
		fmt.Println("这是函数变量对应的函数体")
	} // 注意,这里不加括号表示的是对函数变量进行赋值,调用需要加括号,或者在后面使用变量名加括号

	a() // 调用函数  // 这是函数变量对应的函数体
}
发布了22 篇原创文章 · 获赞 1 · 访问量 1839

猜你喜欢

转载自blog.csdn.net/weixin_42677653/article/details/105174126