函数(2)

@爱耍流氓的唐僧  January 13, 2021

变量作用域
全局变量-是定义在函数外部的变量,它在程序整个运行周期内都有效。 在函数中可以访问到全局变量。
局部变量-又分为两种: 函数内定义的变量无法在该函数外使用,语句块定义的变量,通常我们会在if条件判断、for循环、switch语句上使用这种定义变量的方式,这中变量也只是在语句块中生效。
函数作用域
1.现在函数内部找变量,找不到往外层找
2.函数内部的变量,外部是访问不了的

func test() {
    for i := 0; i < 10; i++ {
        fmt.Println(i) //变量i只在当前for语句块中生效
    }
    //fmt.Println(i) //此处无法使用变量i
}

函数类型与变量

package main
import "fmt"
func f1(){
    fmt.Println("爱耍流氓的唐僧")
}
func f2() int{
        return 10
}
func main(){
    a := f1
    fmt.Printf("%T\n",a)
    b := f2
    fmt.Printf("%T\n",b)
}

输出:

func()
func() int

高阶函数分为函数作为参数和函数作为返回值两部分。
函数能否当成参数传递?

package main
import "fmt"
func f1(){
    fmt.Println("爱耍流氓的唐僧")
}
func f2() int{
        return 10
}
//函数也可以作为参数的类型,有返回值,无参数
func f3(x func() int)  {
    ret := x()
    fmt.Println(ret)
}
func f4(x,y int)int{
    return x + y
}
func main(){
    a := f1
    fmt.Printf("%T\n",a)
    b := f2
    fmt.Printf("%T\n",b)
    f3(f2)//f2这个函数必须符合f3定义的参数函数要求
    f3(b)//b=f2这个函数
}

函数还可以作为返回值么?

package main
import "fmt"
func f1(){
    fmt.Println("爱耍流氓的唐僧")
}
func f2() int{
        return 10
}
//函数也可以作为参数的类型,有返回值,无参数
func f3(x func() int)  {
    ret := x()
    fmt.Println(ret)
}
func f4(x,y int)int{
    return x + y
}
func f5(x func()int) func(int,int) int{
    ret := func(a,b int) int {
        return a + b
    }
    return ret
}
func main(){
    a := f1
    fmt.Printf("%T\n",a)
    b := f2
    fmt.Printf("%T\n",b)
    f3(f2)
    f3(b)
    f7 :=f5(b)
    fmt.Printf("%T\n",f7)//f7就是返回值是一个函数
}

匿名函数就是没有函数名的函数,匿名函数的定义格式如下:

func(参数)(返回值){
    函数体
}

func main() {
    // 将匿名函数保存到变量
    add := func(x, y int) {
        fmt.Println(x + y)
    }
    add(10, 20) // 通过变量调用匿名函数

    //自执行函数:匿名函数定义完加()直接执行
    func(x, y int) {
        fmt.Println(x + y)
    }(10, 20)//只使用一次,立即执行,不需要赋值给变量
}

匿名函数多用于实现回调函数和闭包。

闭包指的是一个函数和与其相关的引用环境组合而成的实体。简单来说,闭包=函数+引用环境。 首先我们来看一个例子:

func adder() func(int) int {
    var x int
    return func(y int) int {
        x += y
        return x
    }
}
func main() {
    var f = adder()
    fmt.Println(f(10)) //10
    fmt.Println(f(20)) //30
    fmt.Println(f(30)) //60

    f1 := adder()
    fmt.Println(f1(40)) //40
    fmt.Println(f1(50)) //90
}

变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。

func main(){
    ret :=test(f2,100,200)
}

func test(x func(int,int),m,n int) func(){
    tmp:=func(){
        x(m,n)
    }
    return tmp
}

func f2(x,y int){
    fmt.println("this is f2")
    fmt.println(x + y)
}

闭包其实并不复杂,只要牢记闭包=函数+引用环境

案例

package main
import "fmt"
func calc(index string, a,b int) int {
    ret := a+b
    fmt.Println(index,a,b,ret)
    return ret
}
func main(){
    a :=1
    b :=2
    defer calc("1",a,calc("10",a,b))
    a=0
    defer calc("2",a,calc("20",a,b))
    b=1
}
分析:
//1. a:=1
//2. b:=2
//3. defer calc("1",1,calc("10",1,2))
//4. calc("10",1,2)//"10" 1 2 3//ret :=3
//5. defer calc("1",1,3)
//6. a=0
//7. defer calc("2",a,calc("20",0,2))
//8. calc("20",0,2)//"20" 0 2 2//ret :=2
//9. defer calc("2",0,2)
//10. b=1
//11. defer calc("1",1,3)//"2" 0 2 2
//12. defer calc("1",1,3)//"1" 1 3 4

QQ图片20210119171429.png


添加新评论