• 使用函数


    函数就是将一段输入数据转换为输出数据的公用代码块

    函数示例

    package main
    
    import "fmt"
    
    func slice_sum(arr []int) int {
        sum := 0
        for _, elem := range arr {
            sum += elem
        }
        return sum
    }
    
    func main() {
        var arr1 = []int{1, 3, 2, 3, 2}
        var arr2 = []int{3, 2, 3, 1, 6, 4, 8, 9}
        fmt.Println(slice_sum(arr1))
        fmt.Println(slice_sum(arr2))
    }

    1、命名返回值,即为返回值预先定义一个名称,最后直接一个return,就可以将预定义的返回值全部返回

    重新定义上面的求和函数,示例代码如下

    func slice_sum(arr []int) (sum int) {
        sum = 0
        for _, elem := range arr {
            sum += elem
        }
        return
    }

    2、函数多返回值,即同时返回多个值

    package main
    
    import "fmt"
    
    func slice_sum(arr []int) (int, float64) {
        sum := 0
        //注意是float64类型
        avg := 0.0
        for _, elem := range arr {
            sum += elem
        }
        avg = float64(sum) / float64(len(arr))
        return sum, avg
    }
    
    func main() {
        var arr = []int{3, 2, 3, 1, 6, 4, 8, 9}
        fmt.Println(slice_sum(arr))
    }

    也可以用预命名返回值名称方式编写函数代码

    func slice_sum(arr []int) (sum int, avg float64) {
        sum = 0
        //注意是float64类型
        avg = 0.0
        for _, elem := range arr {
            sum += elem
        }
        avg = float64(sum) / float64(len(arr))
        return
    }

    3、变长参数;变长参数列表内参数类型都是相同的、可变长参数只能是函数的最后一个参数

    package main
    
    import "fmt"
    
    func sum(base int, arr ...int) int {
        sum := base
        for _, val := range arr {
            sum += val
        }
        return sum
    }
    
    func main() {
        fmt.Println(sum(100, 2, 3, 4))
    }

    变长参数的函数传入切片,如下,注意切片后面的三个点

    func main() {
        var arr = []int{2, 3, 4}
        fmt.Println(sum(100, arr...))
    }

    4、闭包函数:简单理解就是在函数内,定义一个返回函数的变量,可以通过该变量执行其定义的函数,并且在变量函数内可以使用或改变外部函数的变量值

    package main
    
    import "fmt"
    
    func main() {
        var base = 300
        sum := func(arr ...int) int {
            total_sum := base
            for _, val := range arr {
                total_sum += val
            }
            return total_sum
        }
        arr := []int{1, 2, 3, 4}
        fmt.Println(sum(arr...))
    }

    闭包示例:生成偶数序列,输出  0,2,4

    package main
    
    import "fmt"
    
    func createEvenGenerator() func() uint {
        i := uint(0)
        return func() (retVal uint) {
            retVal = i
            i += 2
            return
        }
    }
    
    func main() {
        nextEven := createEvenGenerator()
        fmt.Println(nextEven())
        fmt.Println(nextEven())
        fmt.Println(nextEven())
    }

    5、递归函数,函数内重复调用自己,直到遇到出口,如阶乘函数,出口就是当x=0,示例如下

    package main
    
    import "fmt"
    
    func factorial(x uint) uint {
        if x == 0 {
            return 1
        }
        return x * factorial(x-1)
    }
    
    func main() {
        fmt.Println(factorial(5))
    }

    斐波拉切数列,出口是n=1和n=2

    package main
    
    import "fmt"
    
    func fibonacci(n int) int {
        var retVal = 0
        if n == 1 {
            retVal = 1
        } else if n == 2 {
            retVal = 2
        } else {
            retVal = fibonacci(n-2) + fibonacci(n-1)
        }
        return retVal
    }
    
    func main() {
        fmt.Println(fibonacci(5))
    }

    6、异常处理

    1)defer标注,不论在函数中的什么位置,都是最后执行,即使中间有异常,也会最后执行defer标识的代码,如下面例子,虽然second函数在first函数前面,但是最后执行

    package main
    
    import "fmt"
    
    func first() {
        fmt.Println("first func run")
    }
    
    func second() {
        fmt.Println("second func run")
    }
    
    func main() {
        defer second()
        first()
    }

    defer用于资源释放的案例

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strings"
    )
    
    func main() {
        fname := "D:\test.txt"
        f, err := os.Open(fname)
        defer f.Close()
        if err != nil {
            os.Exit(1)
        }
        bReader := bufio.NewReader(f)
        for {
            line, ok := bReader.ReadString('
    ')
            if ok != nil {
                break
            }
            fmt.Println(strings.Trim(line, "
    "))
        }
    }

    2)、panic触发异常,在defer中使用recover函数接收异常信息,recover只能在defer中才有效,因为异常抛出后,下面的代码不会执行,defer会在最后执行

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        defer func() {
            msg := recover()
            fmt.Println(msg)
        }()
    
        fmt.Println("I am walking and singing...")
        panic("It starts to rain cats and dogs")
    }

    结果图

  • 相关阅读:
    C#校验算法列举
    SuperSocket1.6电子书离线版
    C#检测系统是否激活[转自StackOverFlow]
    WSMBT Modbus & WSMBS Modbus 控件及注册机
    AU3获取系统激活信息
    JavaScript跨浏览器事件处理
    OAuth2的学习小结
    R学习日记——分解时间序列(季节性数据)
    R学习日记——分解时间序列(非季节性数据)
    Java内存分配原理
  • 原文地址:https://www.cnblogs.com/hujiapeng/p/9621373.html
Copyright © 2020-2023  润新知