美文网首页
11 Golang函数详解

11 Golang函数详解

作者: learninginto | 来源:发表于2021-03-24 09:53 被阅读0次

    Go语言中支持:函数、匿名函数和闭包

    • 定义函数使用func关键字
    func 函数名(参数)(返回值){
        函数体
    }
    

    注意:函数名由字母、数字、下划线组成,但不能以字母开头。在同一个包内,函数名不能重名

    //求两个数的和
    func sumFn(x int, y int) int {
        sum := x + y
        return sum
    }
    
    func main(){
        result := sumFn(12, 3)
        fmt.Println(result)//15
    }
    

    函数参数的简写(只能简写前面的)

    func subFn(x, y int) int {
        return x - y;
    }
    
    函数的可变参数

    可变参数其实是一个切片,通过在参数名后加...来标记,可变参数与固定参数结合使用时只能放在后面

    //求n个参数的和
    func sumFn1(x ...int)int{
        fmt.Printf("%v--%T", x, x)
        sum := 0
        for _,v := range x {
            sum += v
        }
        return sum
    }
    //[12 15 8 0]--[]int
    
    
    func main(){
       result := sumFn1(12,15,8,0)
       fmt.Println(result)//35
    }
    

    注意,函数有返回值时,必须指定其类型

    return关键字一次可以返回多个值
    func calc(x, y int) (int, int){
        sum := x + y
        sub := x - y
        return sum, sub
    }
    func main(){
        sum,sub := calc(10, 2)
        fmt.Println(sum, sub)//12 8
    }
    

    返回值命名:函数定义时可以给返回值命名,并在函数体中直接使用这些变量,最后通过return关键字直接返回

    func calc(x, y int) (sum int, sub int){
    //或func calc(x, y int) (sum, sub int){
        sum = x + y
        sub = x - y
        return
    }
    

    封装一个简单的选择排序(升序)

    func sortIntAsc(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 main(){
        var sliceA = []int{1, 5, 3, 0}
        arr := sortIntAsc(sliceA)
        fmt.Println(arr)//[0 1 3 5]
    }
    

    对map按照key的ASCII进行升序排序

    func mapSort(map1 map[string]string) string {
        var sliceKey []string
        //把map对象的key放到切片中
        for k, _ := range map1 {
            sliceKey = append(sliceKey, k)
        }
        //对key进行升序排序
        sort.Strings(sliceKey)
        //循环拼接字符串
        var str string
        for _, v := range sliceKey {
            str += fmt.Sprintf("%v=>%v ", v, map1[v])
        }
        return str
    }
    
    func main(){
        m1 := map[string]string{
            "username":"zhangsan",
            "age":"20",
            "sex":"男",
        }
        str := mapSort(m1)
        fmt.Println(str)
    }
    //age=>20 sex=>男 username=>zhangsan
    
    函数变量作用域(同C语言)
    • 全局变量

    定义在函数外部的变量,在整个程序的运行周期内都有效

    • 局部变量

    在函数内部定义的变量,无法在外部使用

    定义函数类型

    使用type关键字来定义一个calulation类型的函数,它接收两个int类型的参数,并返回一个int类型的返回值

    type calulation func(int, int) int
    

    定义一个calc的类型

    type calc func(int, int) int
    type myInt int
    
    func add(x, y int) int {
        return x + y
    }
    func test(){
        fmt.Println("test...")
    }
    func main(){
        var c clac
        c = add
        fmt.Printf("c的类型:%T", c) //c的类型:main.calc
        //c = test//这里报错了,因为test不满足calc的类型
        fmt.Println(c(10, 5)) //15
        
        f := add
        fmt.Printf("f的类型%T\n", f) //f的类型:func(int, int) int
        fmt.Println(f(15,5))//20
        
        var num1 int = 10
        var num2 myInt = 20
        fmt.Printf("num1的类型%T--num2的类型%T\n", num1, num2)
        //num1的类型int--num2的类型main.myInt
        fmt.Println(num1 + int(num2)) // 30
    }
    
    函数作为另一个函数的参数
    type calcType func(int, int) int
    func add(x, y int)int {
        return x + y
    }
    
    func calc(x, y int, cb calcType) int {
        return cb(x, y)
    }
    
    func main(){
        fmt.Println(calc(10, 20, add))//30
        mult := calc(3, 4, func(x, y int) int{
            return x * y
        })
        fmt.Println(mult)//12
    }
    
    匿名函数

    匿名函数因为没有函数名,所以不能像普通函数那样调用,所以匿名函数需要保存到某个变量活着作为立即执行函数

    func add(x, y int) int {
        return x + y
    }
    func sub(x, y int) int {
        return x - y
    }
    
    //定义一个方法类型
    type calcType func(int, int) int
    
    func do (o string) calcType {
        switch o {
            case "+":
                return add
            case "-":
                return sub
            case "*":
                return func(x, y int) int {
                    return x * y
                }
            default:
                return nil
        }
    }
    
    func main(){
        var a = do("+")
        fmt.Println(a(4, 8)) //12
        b := do("*")
        fmt.Println(b(3, 4)) //12
    }
    
    函数的递归调用(与C一致,尽量避免递归)
    函数的闭包

    闭包是指有权访问另一个函数作用域中的变量的函数,可以让一个变量常驻内存且不污染全局变量。

    func adder() func() int {
        var i = 10 //常驻内存,不污染全局
        return func() int {
            return i + 1
        }
    }
    
    func adder2() func(y int) int {
        var i = 10
        return func(y int) int {
            i += y
            return i
        }
    }
    
    func main(){
        var fn = adder()
        fmt.Println(fn())//11
        fmt.Println(fn())//11
        fmt.Println(fn())//11
        
        var fn2 = adder2()
        fmt.Println(fn(10))//20
        fmt.Println(fn(2))//22
        fmt.Println(fn(1))//23
    }
    

    注意:由于闭包的作用域中返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存。过度使用闭包会导致性能下降,所以,在非必要时不建议使用闭包。

    相关文章

      网友评论

          本文标题:11 Golang函数详解

          本文链接:https://www.haomeiwen.com/subject/hqpchltx.html