golang学习笔记12-函数(一):定义与使用

注:本人已有C,C++,Python基础,只写本人认为的重点。

一、基本语法

go的函数和C/C++的也很像,语法如下:
func 函数名(形参列表)返回值类型列表{
//执行语句
return 返回值列表
}
其中形参列表为:变量名1 变量类型1,变量名2 变量类型2,…,变量名n 变量类型n,返回列表为变量类型1,变量类型2,…,变量类型n,实例如下:

func cal(num1 int, num2 int) int {
	var sum int = 0
	sum += num1
	sum += num2
	return sum
}

显然,形参列表和C/C++的区别无非是变量类型写在后面,这里return的机制也一样。但形参列表还可以是可变参数列表,语法为:
func 函数名(变量名…变量类型)返回值类型列表{
//执行语句
return 返回值列表
}
可变参数接收任意数量参数,在函数内部会被视为切片,用len函数即可获取其长度,示例如下:

package main

import "fmt"

//定义一个函数,函数的参数为:可变参数 ...  参数的数量可变
//args...int 可以传入任意多个数量的int类型的数据  传入0个,1个,,,,n个
func test(args ...int) {
	//函数内部处理可变参数的时候,将可变参数当做切片来处理
	//遍历可变参数:
	for i := 0; i < len(args); i++ {
		fmt.Println(args[i])
	}
}
func main() {
	test()
	fmt.Println("--------------------")
	test(3)
	fmt.Println("--------------------")
	test(37, 58, 39, 59, 47)
}

不难发现,上述例子中无返回值,所以无需return,也就无需写返回列表。但return还有个额外机制:当返回列表存在且声明了函数内的变量名时,有以下两种情况:
1.只写return,那么返回变量的顺序由返回列表的变量名决定
2.return后跟变量名,那么return的优先级会高于返回列表,返回顺序由return后的变量名决定
示例如下:

package main

import "fmt"

func cal(num1 int, num2 int) (sub int, sum int) {
	sum = num1 + num2
	sub = num1 - num2
	return //无返回值,按返回列表的名字顺序返回
}
func cal2(num1 int, num2 int) (sub int, sum int) {
	sum = num1 + num2
	sub = num1 - num2
	return sum, sub //return优先级高于返回列表
}
func main() {
	sub, sum := cal2(1, 2) //按返回列表,sub=-1,sum=3
	//但结果不是这样
	fmt.Println("sum=", sum, "sub=", sub)
}

二、函数的传递

我在第七节(golang学习笔记7)中讲过,函数是值类型的数据类型,但有引用特性,所以当函数赋给一个变量时,传递的是引用而不是函数代码本身,示例如下:

package main

import "fmt"

//定义一个函数:
func test(num int) {
	fmt.Println(num)
}

//定义一个函数,把另一个函数作为形参:
func test02(num1 int, num2 float32, testFunc func(int)) {
	fmt.Println("-----test02")
}
func main() {
	//函数也是一种数据类型,可以赋值给一个变量
	a := test //变量就是一个函数类型的变量
	fmt.Printf("a的类型是:%T,test函数的类型是:%T \n", a, test)
	//a的类型是:func(int),test函数的类型是:func(int)
	//通过该变量可以对函数调用
	a(10) //等价于  test(10)
	//调用test02函数:
	test02(10, 3.19, test)
	test02(10, 3.19, a)
}

不难发现,test和C/C++中的函数指针很像,但C/C++中的函数不是数据类型,其传递要通过指针来操控,而go把函数单独作为一个数据类型,脱离了指针的控制。
如果你觉得testFunc func(int)可以再简化,go提供了type关键字,类似C/C++的typedef,但也有明显区别:typedef定义的类型可完全替代原类型,而type定义的类型赋值时,go编译器还是认为和原类型不是一个类型。示例如下:

package main

import "fmt"

//定义一个函数:
func test(num int) {
	fmt.Println(num)
}

type myFunc func(int)

//定义一个函数,把另一个函数作为形参:
func test02(num1 int, num2 float32, testFunc myFunc) {
	fmt.Println("-----test02")
	fmt.Printf("num1=%d,num2=%.2f\n", num1, num2)
}
func main() {
	a := test
	type myInt int
	num1 := 1
	var num3 myInt
	num1 = int(num3) //go编译器仍然认为myInt不是int,所以需要强转
	num2 := 1.1
	test02(num1, float32(num2), a)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值