day02
一、函数
1. 函数结构
func:函数由func开始声明
FuncName:函数名称,根据约定,函数名首字母小母为private;大写为public
参数列表: 函数可以有0个或多个参数,参数格式为:变量名 类型(如果有多个参数以逗号 分隔,不支持默认参数)
返回类型:
1>下面返回值声明了两个变量,这不是必须的,可以只有类型没有变量名
2>如果只有一个返回值且不声明返回值变量,可以省略(包括返回值括号)
3>如果没有返回值 ,直接省略最后的返回信息
4>如果有返回值 ,必须在函数体内加上return语句
func FuncName(参数列表) (o1 type1, o2 type2 返回类型){
函数体
return
}
2. 无参数无返回值函数
func test() {
fmt.Println("无参数无返回值")
}
func main() {
test()
}
3. 有参数无返回值函数
func test(a int) {
a += 1
fmt.Println(a)
}
func test2(a int, b int) {
sum := a + b
fmt.Println(sum)
}
func test3(a, b int) {
sum := a + b
fmt.Println(sum)
}
func test4(a int, b string, c float64) {
fmt.Println("a=", a)
fmt.Println("b=", b)
fmt.Println("b=", c)
}
func test5(a, b int, c, d string, e float64) {
}
4. 不定参数无返回值函数
传递的参数可以是0或多个
func test(args ...int) {
fmt.Println(len(args)) //显示参数个数
}
func test2(a int, args ...int) {
fmt.Println(len(args)) //显示参数个数
}
func test3(args ...int, a int) {
fmt.Println(len(args)) //这种写法错误不定参数一定要写在参数列表的最后一个(会导致编译不过)
}
func test4(args ...int, b ...string) {
fmt.Println(len(args)) //只能有一个不定参数(会导致编译不过)
}
func main() {
test()
test(1)
test(1, 2)
test(1, 2, 3)
}
5. 不定参数传递无返回值函数
func sayOut(args ...int) {
for _, data := range args {
fmt.Println(data)
}
}
func test(args ...int) {
fmt.Println("test")
sayOut(args...) //不定参数全部传递
}
func test2(args ...int) {
fmt.Println("test2")
sayOut(args[:2]...) //不定参数传递第1个到第2个(包括第2个)
}
func test3(args ...int) {
fmt.Println("test3")
sayOut(args[2:]...) //不定参数传递第2个到最后一个(不包括第2个)
}
func test4(args ...int) {
fmt.Println("test4")
sayOut(args[1:3]...) //不定参数传递第1个到第3个(不包括第1个)
}
func main() {
test(1, 2, 3, 4, 5)
test2(1, 2, 3, 4, 5)
test3(1, 2, 3, 4, 5)
test4(5, 4, 3, 2, 1)
}
6. 无参一个返回值
func test() int {
return 666
}
func test2() (result int) {
return 666 // 官方推荐写法
}
func test3() (result int) {
result = 666 // 常用写法
return
}
func test4() (result int) {
result = 666
return result
}
func main() {
a := test4()
fmt.Println(a)
}
7. 多个返回值
func test() (int, int, int) {
return 1, 2, 3
}
func test2() (a int, b int, c int) {
a, b, c = 1, 2, 3 // 官方推荐写法
return
}
func test3() (a, b, c int) {
a, b, c = 1, 2, 3 // 官方推荐写法
return
}
func test4() (a, b, c int) {
a, b, c = 1, 2, 3
return a, b, c
}
func main() {
a, b, c := test4()
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
8. 有参数有返回值
func complexs(num1, num2 int) (max, min int) {
if num1 > num2 {
num1, num2 = num2, num1
}
max = num2
min = num1
return
}
func main() {
max, min := complexs(10, 20)
fmt.Println("max=", max)
fmt.Println("min=", min)
}
9. 递归函数
func sum(max int) (result int) {
if max == 1 {
return 1
}
result = max + sum(max-1)
return
}
func main() {
sum := sum(100)
fmt.Println(sum)
}
10. 函数类型
函数也是一种数据类型,可以通过type给函数起一个别名(相同入参数(类型和个数)和相同返回(类型和个数)值可以定义成同一种type)
func add(a, b int) (result int) {
result = a + b
return
}
func add1(a int, b int) (result int) {
result = a + b
return
}
func add2(a int, b int) int {
return a + b
}
//func add3(a int, b int) {
// result = a + b
//}
func minus(a, b int) (result int) {
result = a - b
return
}
type funcType func(a, b int) (result int)
func main() {
types := add
result := types(10, 2)
fmt.Println(result)
types = minus
result = types(10, 2)
fmt.Println(result)
types = add1
result = types(10, 2)
fmt.Println(result)
types = add2
result = types(10, 2)
fmt.Println(result)
// types = add3
// result = types(10, 2)错误的不能用
// fmt.Println(result)
}
11. 回调函数,(通过函数类型,实现多态)
type calFuncType func(num1, num2 int) int
func add(num1, num2 int) int {
return num1 + num2
}
func minus(num1, num2 int) int {
return num1 - num2
}
func multi(num1, num2 int) int {
return num1 * num2
}
func chu(num1, num2 int) int {
return num1 / num2
}
func cals(num1, num2 int, funcType calFuncType) int {
return funcType(num1, num2)
}
func main() {
result := cals(10, 2, add)
fmt.Println(result)
result = cals(10, 2, minus)
fmt.Println(result)
result = cals(10, 2, multi)
fmt.Println(result)
result = cals(10, 2, chu)
fmt.Println(result)
}
12. 匿名函数与闭包
匿名函数没有函数名
fun(){
}
闭包:一个函数捕获了和它在同一作用的其他变量和常量。这就意味着闭包被调用时,不管程序在什么地方调用,闭包能够使用这些常量和变量。它不关心这些捕获了的变量和常量是否已经超出了作用域,所以只要闭包还在使用它们,这些变量和常量就还会存在
a := 1
b := "abc"
//匿名函数声明(常用)
f1 := func() {
fmt.Println(a)
fmt.Println(b)
}
//匿名函数调用(常用)
f1()
//匿名函数调用(不常用)
type funcType func()
var types funcType
types = f1
types()
//匿名函数声明同时调用
func() {
fmt.Println(a)
fmt.Println(b)
}() //()代表调用匿名函数
//带参匿名函数声明并调用
func(a, b int) {
fmt.Println(a)
fmt.Println(b)
}(1, 2) //()代表调用匿名函数
//有返回值匿名函数声明并调用
x := func(a, b int) int {
return a + b