• 第三章 go语言函数


    一、函数基础

      定义:有输入、有输出、用来执行一个指定任务的代码块

    func 函数名(形参列表)(返回值列表){
        执行代码
        return 返回值列表
    }
    
    //无参数和返回值
    func test(){
        fmt.Println("helloWorld")
    }
    func main(){
        test()
    }
    
    //函数的多返回值
    func test(x,y int,z string) (int,string){
        //类型相同的相邻参数x,y参数类型可以合并
        //多返回值得用括号括起来
        n := x+y
        return n,z
    }
    
    //返回值进行命名
    func test2(a,b int) (sum int,sub int) {
        sum = a+b
        sub = a-b
        return
    }
    func main(){
        sum,sub := test2(100,800)
        fmt.Println(sum,sub)
    }
    
    //可变参数
    func test3(b ...int) int{
        sum :=0
        for i := 0;i<len(b);i++{
            sum = sum + b[i]
        }
        return sum
    }
    func main(){
        sum := test3(10,20)    //可以传任意个参数
        fmt.Printf("sum=%d
    "),sum)
    }
    

    二、函数defer语句

        定义:在一个函数中有defer语句时,只有到返回的时候才会执行,多个defer时执行顺序是从后往前,多用于资源脂肪,使用defer关闭资源

    func test(){
        defer fmt.Println("Hello")
        fmt.Println("Parallel")
        fmt.Println("World")
    )
    //结果    Parallel  World  Hello
    
    func test2(){
        defer fmt.Println("Hello")
        defer fmt.Println("Hello1")
        defer fmt.Println("Hello2")
        fmt.Println("Parallel")
        fmt.Println("World")
    }
    //结果    Parallel  World  Hello2  Hello1  Hello
    
    fun test3(){
        for i:=0;i<5;i++{
            defer fmt.Println(i)
        }
    }
    //结果    4  3  2  1  0
    
    func test4(){
        i := 0
        defer fmt.Println(i)
        i = 1000
        fmt.Println(i)
    }
    //结果    1000 0    当执行代码到defer时,参数已经传入,但是最后执行
    

    三、内置函数

        close:主要用来关闭channel(管道)

        len:用来求长度(如:string,array,slice,map,channel)

        new:用来初始化int、struct,返回指针  var a = new(int):得到一个int类型的指针

        make:用来初始化channel,map,slice

        append:用来追加元素到slice

        panic和recover:用来做错误处理  

      变量作用域和可见性

    //作用域:全局变量,在函数最外层
    var a int = 100
    func test(){
        fmt.Printf("a = %d
    ",a)
    }
    
    //作用域:局部变量(1.函数内定义2.语句块内定义)
    func add(a int,b int) int {
        var sum int = 0    //sum是局部变量
        if a>0{
            var c int = 100    //c是局部变量,只在if语句块有效
        }
    }
    
    //可见性:包内任何变量或函数都是能访问的,首字母大写是可以导出的,能够被其他包访问或调用,小写表示私有,不能被嗲用
    package caic
    var a int = 100
    var A int = 200
    func Add(a,b int) int{
        return a+b
    }
    func sub(a,b int) int{
        return a-b
    }
    
    package caic
    func Test()int{
        return a
    }    //包名相同,可以调用
    
    package main
    import ("fmt","caic")
    func main(){
        var s1 int = 200
        var s2 int = 300
        sum := calc.Add(s1,s2)
        fmt.Printf("s1+s2=%d",sum)    //500
        fmt.Printf("caic.A=%d",caic.A)    //200
        fmt.Printf("caic.a=%d",caic.Test())
    }    //可以调用caic包中的Add函数和Test函数还有大写的的变量
    

    四、匿名函数

    //函数是一种类型,因此可以定义一个函数类型的变量
    func add(a,b int) int{
        return a + b
    }
    func testFunc1(){
        f1:=add
        fmt.Printf("type of f1 = %T
    ",f1)    //打印变量用%T
        sum := f1(2,5)    //函数类型的变量
        fmt.Printf("sum=%d
    ",sum)
    }
    func main(){
        testFunc1()
    }
    
    //匿名函数,没有命名的函数
    func testFunc2(){
        f1 := func(a,b int) int{    //匿名函数
            return a+b
        }
        fmt.Printf("type of f1=%T
    ",f1)
        sum := f1(2,5)
        fmt.Printf("sum = %d
    ",sum)
    }
    funt main(){
        testFunc2()
    }
    
    //defer使用匿名函数
    func testFunc3(){    
        defer func(){
            fmt.Printf("defer i=%d
    ",i)    //100
        }()
        i = 100
        fmt.Printf("i=%d
    ",i)
    }
    
    //函数作为一个参数
    func add(a,b int) int{
        return a+b
    }
    func sub(a,b int) int{
        return a-b
    }
    func calc(a,b int,op func(int,int)int)int{
        return op(a,b)
    }
    func testDefer5(){
        sum := calc(100,300,add)
        sub := calc(100,300,sub)
        fmt.Printf("sum-%d sub-%d
    ",sum,sub)
    }

    五、函数闭包

        定义:一个函数和与其相关的引用环境组合而成的实体(匿名函数嵌套,闭包是外部函数嵌套内部函数,内部函数引用外部函数的变量,外部函数用完变量后,被内部函数引用并保留下来,作为自由变量使用,就是闭包)

    func Adder() func(int) int{
        var x int
        return func(d int) int{
            x += d
            return x
        }
    }
    func testClosure1(){
        f:= Adder()
        ret := f(1)
        fmt.Printf("ret=%d
    ",ret)    //1
        ret = f(20)
        fmt.Printf("ret%d
    ",ret)    //21
        ret = f(300)
        fmt.Printf("ret=%d
    ",ret)    //321
    }
    
    //test
    func add(base int) func(int) int{
        return func (i int) int{
            base += i
            return base
        }
    }
    func testClosure1(){
        tmp1 := add(10)
        fmt.Println(tmp1(1),tmp1(2))
        tmp2 := add(100)
        fmt.println(tmp2(1),tmp2(2))
    }
    
    //test2
    func test(suffix string) func(string) string{
        return func(name string) string{
            if !strings.HasSuffix(name,suffix){
                return name + suffix
            }
            return name
        }
    }
    func testClosure1(){
        func1 := test(".bmp")
        func2 := test(".jpg")
        fmt.Println(func1("test"))    //test.bmp
        fmt.Println(func2("test"))    //test.jpg
    }
    
    //test3
    func calc(base int) (func(int) int,func(int) int) {
        add := func(i int) int{
            base += i
            return base
        }
        return add,sub
    }
    func testClosure1(){
        f1,f2 := calc(10)
        fmt.Println(f1(1),f2(2))    //11 9
        fmt.Println(f1(3), f2(4))    //12 8
        fmt.Println(f1(5), f2(6))    //13 7
        fmt.Println(f1(7), f2(8))    //14 6
    }
    
    //test4
    func testClosure1(){
        for i:=0;i<5;i++{
            go func(){
                Fmt.Println(i)
            }()
        }
        time.Sleep(time.Second)
    }
    //输出    55555    有坑,每次i会赋值给函数中,但到5时才打印
    
    //test5
    func testClosure1(){
        for i:=0;i<5;i++{
            go func(index int) {
                fmt.Println(index)
            }(i)
        }
        time.Sleep(time.Second)
    }
    //输出    01234
    

      

      

  • 相关阅读:
    牛客小白月赛3 I 排名【结构体排序/较复杂/细节】
    牛客小白月赛3 F 异或【区间交集】
    牛客小白月赛3 B 躲藏【动态规划/字符串出现cwbc子序列多少次】
    陕西师范大学第七届程序设计竞赛网络同步赛 I 排队排队排队【数组任一位可以移动到队头,最少移动几次增序/数组指针操作】
    陕西师范大学第七届程序设计竞赛网络同步赛 J 黑猫的小老弟【数论/法拉数列/欧拉函数】
    陕西师范大学第七届程序设计竞赛网络同步赛D ZQ的睡前故事【约瑟夫环1-N数到第k个出队,输出出队顺序/ STL模拟】
    陕西师范大学第七届程序设计竞赛网络同步赛 C iko和她的糖【贪心/ STL-优先队列/ 从1-N每个点有能量补充,每段有消耗,选三个点剩下最多能量】
    陕西师范大学第七届程序设计竞赛网络同步赛 F WWX的礼物【数学/k进制下x^n的位数/log】
    NYOJ 71 乘船问题【贪心】
    hdu 5273 Dylans loves sequence
  • 原文地址:https://www.cnblogs.com/parallel-Y/p/11412602.html
Copyright © 2020-2023  润新知