golang初级进阶(三):函数(上)

目录

一、函数定义

二、函数调用

三、封装具体函数

1. 封装

 2. 引用

3. 注意:函数是一个引用类型,会改变原切片的值

四、函数中变量作用域

1. 程序运行中的全局变量

2. main中的全局变量

3. 局部变量

五、高级函数

1. 自定义类型:type

2. 函数作为参数

3. 函数作为返回值

4. 匿名函数

 5. 递归函数

 6. 闭包:函数内部返回函数,并且可以拿到函数内部定义的局部变量


一、函数定义

函数是组织好的、可重复使用的、用于执行指定任务的代码块。

初级定义函数:5种方式

// 定义函数 第一种方式:每个参数都有规定类型,返回值类型。
func sum1(x int, y int) int {
	sum := x + y
	return sum
}

// 第二种方式:参数的类型一致
func sum2(x, y int) int {
	sum := x + y
	return sum
}

// 第三种方式:不规定参数数量,此时接收到的参数是一个切片
func sum3(x ...int) int {
	// 此时接收到的x是一个切片[1,2,3,4,1,2]
	sum := 0
	for _, v := range x {
		sum += v
	}
	return sum
}

// 第四种方式:返回多个值
func sum4(x, y int) (int, int) {
	return x, y
}
// 第四种的第二种定义方式
func sum41(x, y int) (x1, y1 int) {
	x1 = x
	y1 = y
	return
}

// 第五种:没有参数
func sum5() int {
	return 8
}

二、函数调用

    // 调用函数:
	sum1 := sum1(1, 3)
	fmt.Println(sum1) // 4

	sum2 := sum2(5, 1)
	fmt.Println(sum2) // 6

	sum3 := sum3(1, 2, 3, 4)
	fmt.Println(sum3) // 10,此时sum3里面的参数为[1, 2, 3, 4]

	x, y := sum4(5, 4)
	fmt.Println(x, y) // 5 4

    x1, y1 := sum41(6, 9)
	fmt.Println(x1, y1) // 6 9

	sum5 := sum5()
	fmt.Println(sum5) // 8

三、封装具体函数

1. 封装

// 封装算法 切片升序
func sortArrAsc(slice []int) []int {
	for i := 0; i < len(slice); i++ {
		for j := i + 1; j < len(slice); j++ {
			if slice[i] > slice[j] {
				temp := slice[i]
				slice[i] = slice[j]
				slice[j] = temp
			}
		}
	}

	return slice
}

// 封装算法 切片降序
func sortArrDesc(slice []int) []int {
	for i := 0; i < len(slice); i++ {
		for j := i + 1; j < len(slice); j++ {
			if slice[i] < slice[j] {
				temp := slice[i]
				slice[i] = slice[j]
				slice[j] = temp
			}
		}
	}

	return slice
}

// 按照key排序并输出
func sliceKey(mapArr map[string]string) string {
	// 1. 先拿到key 进行排序
	var key []string
	for k, _ := range mapArr {
		key = append(key, k)
	}
	sort.Strings(key)
	// 2. 根据key打印字符串
	var r string
	for _, v := range key {
		r += fmt.Sprintf("%v=>%v,", v, mapArr[v])
	}

	return r
}

 2. 引用

    /**
	函数基本封装
	*/
	var sliceA = []int{32, 441, 12, 33, 1}
	fmt.Println(sortArrAsc(sliceA))  // [1 12 32 33 441]
	fmt.Println(sortArrDesc(sliceA)) // [441 33 32 12 1]

	var sliceB = map[string]string{
		"username": "jason",
		"age":      "12",
		"sex":      "man",
	}
	fmt.Println(sliceKey(sliceB)) // age=>12,sex=>man,username=>jason,

3. 注意:函数是一个引用类型,会改变原切片的值

    // 函数是一个引用类型,所以均已改变原来的切片值。
	fmt.Println(sliceA) // [441 33 32 12 1]
	fmt.Println(sliceB) // map[age:12 sex:man username:jason]

四、函数中变量作用域

1. 程序运行中的全局变量

package main

import "fmt"

// 程序运行中的全局变量
var flags bool = true

func test() bool {
	if flags {
		return true
	} else {
		return false
	}
}

func main() {
    // 程序运行中的全局变量
	var tests = test()
	if tests {
		fmt.Println("true")
	}
}

2. main中的全局变量

func main() {
    // main函数中的全局变量
	var flag bool = true
	if flag {
		fmt.Println("true")
	}
}

3. 局部变量

    // 局部变量
	if flagss := true; flagss {
		fmt.Println("true")
	}

五、高级函数

1. 自定义类型:type

// 定义类型 type关键字
type calc func(int, int) int // 定义calc是一个函数类型
type myInt int               // 自定义int类型

func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}

func main() {
    var c calc
	c = add
	fmt.Printf("c的类型是:%T\n", c) // c的类型是:main.calc

	c1 := add
	fmt.Printf("c1的类型是:%T\n", c1) // c1的类型是:func(int, int) int

    var a myInt = 8
	b := 2
	fmt.Printf("a => %T b => %T\n", a, b) // a => main.myInt b => int
	fmt.Println(int(a) + b)               // 10 要先转换才能相加
}

2. 函数作为参数

// 函数作为参数
func acts(x, y int, tion calc) int {
	return tion(x, y)
}

// 第二种方式,参数函数是匿名函数
func acts2(x, y int, tion func(int, int) int) int {
	return tion(x, y)
}

func main() {
    s := acts(15, 5, sub) // sub函数作为参数传递至acts函数内
	fmt.Println(s)        // 10

	s2 := acts2(10, 5, add)
	fmt.Println(s2) // 15
}

3. 函数作为返回值

// 函数作为返回值,返回值函数为匿名函数
func do(s string) func(int, int) int {
	switch s {
	case "+":
		return add
	case "-":
		return sub
	default:
		return nil
	}
}

func main() {
    var dos = do("+")
	fmt.Println(dos(1, 2)) // 3
}

4. 匿名函数

    // 匿名函数:第一种赋予变量
	var adds = func(x, y int) int {
		return x + y
	}
	fmt.Println(adds(3, 2)) // 5

	// 第二种,直接在函数体后面加括号,函数可以直接执行
	func(x, y int) {
		fmt.Println(x - y) // 2
	}(5, 3)

 5. 递归函数

// 递归函数:倒叙打印n到1的数据
func fn1(n int) {
	if n > 0 {
		fmt.Println(n)
		n--
		fn1(n)
	}
}

// 递归函数2:计算1到n的和
func fn2(n int) int {
	if n > 1 {
		return n + fn2(n-1)
	} else {
		return 1
	}
}

func main() {
    // 打印出10到1的值
	fn1(10)
	// 计算出1-100的和
	fmt.Println(fn2(100)) // 5050
}

 6. 闭包:函数内部返回函数,并且可以拿到函数内部定义的局部变量

package main

import "fmt"

// 闭包函数: 函数内部返回函数,并且可以拿到函数内部定义的局部变量
func fn3() func() int {
	var i = 10
	return func() int {
		return i
	}
}

func fn4() func(int) int {
	var x = 10
	return func(y int) int {
		x += y
		return x
	}
}

// 闭包进阶1:
func fn5(x int) func(int) int {
	return func(y int) int {
		x += y
		return x
	}
}

// 闭包进阶2:
func fn6(name string) func(string) string {
	return func(end string) string {
		return name + end
	}
}

// 闭包进阶3:
func fn7(x int) (func(int) int, func(int) int) {
	add := func(i int) int {
		base := x + i
		return base
	}

	sub := func(i int) int {
		base := x - i
		return base
	}

	return add, sub
}

func main() {
    var f = fn3()    // fn3 代表f是个方法,fn3()代表执行fn3这个方法。此时f就是闭包返回出来的方法。
	fmt.Println(f()) // 10

	var f2 = fn4()     // 不好理解
	fmt.Println(f2(1)) // 11
	fmt.Println(f2(1)) // 12
	fmt.Println(f2(1)) // 13

	var f5 = fn5(10)
	fmt.Println(f5(10)) // 20
	fmt.Println(f5(20)) // 40
	fmt.Println(f5(30)) // 70

	var f6 = fn6("test")
	fmt.Println(f6(".jpg")) // test.jpg
	fmt.Println(f6(".png")) // test.png

	var f7, f8 = fn7(10)
	fmt.Println(f7(5), f8(5)) // 15 5
	fmt.Println(f7(3), f8(2)) // 13 8
	fmt.Println(f7(6), f8(1)) // 16 9
}

你可能感兴趣的:(进军golang,go,函数,递归,闭包)