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 可以,因为它有这个变量的内存地址的 引用。

 

原文地址:https://www.cnblogs.com/saryli/p/12165226.html