zoukankan      html  css  js  c++  java
  • golang学习笔记 ---Function

    package main
    
    import "fmt"
    
    // 这里是一个函数,接受两个 `int` 并且以 `int` 返回它们的和
    func plus(a int, b int) int {
    
        // Go 需要明确的返回,不会自动返回最
        // 后一个表达式的值
        return a + b
    }
    
    // 当多个连续的参数为同样类型时,最多可以仅声明最后一个参数类型
    // 而忽略之前相同类型参数的类型声明。
    func plusPlus(a, b, c int) int {
        return a + b + c
    }
    
    func main() {
    
        // 通过 `name(args)` 来调用函数,
        res := plus(1, 2)
        fmt.Println("1+2 =", res)
    
        res = plusPlus(1, 2, 3)
        fmt.Println("1+2+3 =", res)
    }
    

      Go 函数有很多其他的特性。其中一个就是多值返回

    package main
    
    import "fmt"
    
    // `(int, int)` 在这个函数中标志着这个函数返回 2 个 `int`。
    func vals() (int, int) {
        return 3, 7
    }
    
    func main() {
    
        // 这里我们通过_多赋值_操作来使用这两个不同的返回值。
        a, b := vals()
        fmt.Println(a)
        fmt.Println(b)
    
        // 如果你仅仅需要返回值的一部分的话,你可以使用空白标识符`_`。
        _, c := vals()
        fmt.Println(c)
    }
    

      可变参数函数。在调用时可以用任意数量的参数。 例如,fmt.Println 是一个常见的变参函数。

    package main
    
    import "fmt"
    
    // 这个函数接受任意数目的 `int` 作为参数。
    func sum(nums ...int) {
        fmt.Print(nums, " ")
        total := 0
        for _, num := range nums {
            total += num
        }
        fmt.Println(total)
    }
    
    func main() {
    
        // 变参函数使用常规的调用方式,传入独立的参数。
        sum(1, 2)
        sum(1, 2, 3)
    
        // 如果你有一个含有多个值的 slice,想把它们作为参数
        // 使用,你要这样调用 `func(slice...)`。
        nums := []int{1, 2, 3, 4}
        sum(nums...)
    }
    

    Go 函数的另一个关键的方面是闭包结构

    Go 支持匿名函数,并能用其构造 闭包。 匿名函数在你想定义一个不需要命名的内联函数时是很实用的。

    package main
    
    import "fmt"
    
    // 这个 `intSeq` 函数返回另一个在 `intSeq` 函数体内定义的
    // 匿名函数。这个返回的函数使用闭包的方式 _隐藏_ 变量 `i`。
    func intSeq() func() int {
        i := 0
        return func() int {
            i++
            return i
        }
    }
    
    func main() {
    
        // 我们调用 `intSeq` 函数,将返回值(一个函数)赋给
        // `nextInt`。这个函数的值包含了自己的值 `i`,这样在每
        // 次调用 `nextInt` 时都会更新 `i` 的值。
        nextInt := intSeq()
    
        // 通过多次调用 `nextInt` 来看看闭包的效果。
        fmt.Println(nextInt())
        fmt.Println(nextInt())
        fmt.Println(nextInt())
    
        // 为了确认这个状态对于这个特定的函数是唯一的,我们
        // 重新创建并测试一下。
        newInts := intSeq()
        fmt.Println(newInts())
    }
    

      Go 支持 递归。 这里是一个经典的阶乘示例

    package main
    
    import "fmt"
    
    // `fact` 函数在到达 `fact(0)` 前一直调用自身。
    func fact(n int) int {
        if n == 0 {
            return 1
        }
        return n * fact(n-1)
    }
    
    func main() {
        fmt.Println(fact(7))
    }
    

      Go 支持 指针, 允许在程序中通过引用传递值或者数据结构。

    package main
    
    import "fmt"
    
    // 我们将通过两个函数:`zeroval` 和 `zeroptr` 来比较指针和
    // 值类型的不同。`zeroval` 有一个 `int` 型参数,所以使用值
    // 传递。`zeroval` 将从调用它的那个函数中得到一个 `ival`
    // 形参的拷贝。
    func zeroval(ival int) {
        ival = 0
    }
    
    // `zeroptr` 有一和上面不同的 `*int` 参数,意味着它用了一
    // 个 `int`指针。函数体内的 `*iptr` 接着_解引用_这个指针,
    // 从它内存地址得到这个地址对应的当前值。对一个解引用的指
    // 针赋值将会改变这个指针引用的真实地址的值。
    func zeroptr(iptr *int) {
        *iptr = 0
    }
    
    func main() {
        i := 1
        fmt.Println("initial:", i)
    
        zeroval(i)
        fmt.Println("zeroval:", i)
    
        // 通过 `&i` 语法来取得 `i` 的内存地址,即指向 `i` 的指针。
        zeroptr(&i)
        fmt.Println("zeroptr:", i)
    
        // 指针也是可以被打印的。
        fmt.Println("pointer:", &i)
    }
    

      zeroval 在 main 函数中不能改变 i 的值,但是 zeroptr 可以,因为它有这个变量的内存地址的 引用。

     

  • 相关阅读:
    软件策划书
    对开发团队的看法
    对敏捷开发的认识
    企业单位
    Pg数据库的基础安装
    Windows Server 任务计划执行.exe
    2020.04.08 重新开始
    20200211 Oracle监听启动异常
    20191225 医疗行业数据仓库
    20191224 多维数据库
  • 原文地址:https://www.cnblogs.com/saryli/p/12165226.html
Copyright © 2011-2022 走看看