目录
一、函数定义
二、函数调用
三、封装具体函数
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
}
二、函数调用
// 调用函数:
sum 1 := 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
}