1. 定义和调用函数

1.1 基本函数定义

函数的基本定义格式如下:

func functionName(parameterList) returnType {
    // 函数体
}

例如:

package main

import "fmt"

// 定义一个返回值为int的函数
func add(a int, b int) int {
    return a + b
}

func main() {
    result := add(3, 4)
    fmt.Println(result) // 输出: 7
}

1.2 无返回值的函数

package main

import "fmt"

// 无返回值的函数
func greet(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    greet("Alice") // 输出: Hello, Alice
}

1.3 多返回值的函数

Go语言允许函数返回多个值。

package main

import "fmt"

// 返回两个int类型值的函数
func swap(a, b int) (int, int) {
    return b, a
}

func main() {
    x, y := swap(1, 2)
    fmt.Println(x, y) // 输出: 2 1
}

1.4 命名返回值

可以为返回值命名,并在函数体中直接使用这些变量。

package main

import "fmt"

// 命名返回值
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return // 直接返回命名返回值
}

func main() {
    fmt.Println(split(17)) // 输出: 7 10
}

2. 参数传递

2.1 值传递

Go语言中的参数传递默认是值传递,即传递参数的副本。

package main

import "fmt"

func modify(a int) {
    a = 10
}

func main() {
    x := 5
    modify(x)
    fmt.Println(x) // 输出: 5,原值不变
}

2.2 引用传递

通过传递指针,可以实现引用传递,函数可以修改原始变量的值。

package main

import "fmt"

func modify(a *int) {
    *a = 10
}

func main() {
    x := 5
    modify(&x)
    fmt.Println(x) // 输出: 10,原值被修改
}

3. 可变参数

使用 ... 语法,可以定义可变参数函数。

package main

import "fmt"

// 可变参数函数
func sum(numbers ...int) int {
    total := 0
    for _, number := range numbers {
        total += number
    }
    return total
}

func main() {
    fmt.Println(sum(1, 2, 3)) // 输出: 6
    fmt.Println(sum(4, 5, 6, 7)) // 输出: 22
}

4. 匿名函数和闭包

4.1 匿名函数

匿名函数是没有名字的函数,可以在变量中存储和传递。

package main

import "fmt"

func main() {
    // 定义并调用匿名函数
    func(message string) {
        fmt.Println(message)
    }("Hello, Go!")
}

4.2 闭包

闭包是一个函数值,它引用了函数体之外的变量。

package main

import "fmt"

// 闭包函数
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(pos(i), neg(-2*i))
    }
}

5. 方法

方法是绑定到特定类型的函数。

package main

import "fmt"

type Circle struct {
    Radius float64
}

// 绑定到Circle类型的方法
func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

func main() {
    c := Circle{Radius: 5}
    fmt.Println(c.Area()) // 输出: 78.5
}

6. 递归函数

函数可以调用自身,实现递归。

package main

import "fmt"

// 递归函数计算阶乘
func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}

func main() {
    fmt.Println(factorial(5)) // 输出: 120
}

7. defer、panic和recover

7.1 defer

defer 语句会将函数推迟到外层函数返回之后执行。

package main

import "fmt"

func main() {
    defer fmt.Println("world")
    fmt.Println("hello")
}

7.2 panic

panic 用于引发恐慌,导致程序中止执行。

package main

import "fmt"

func main() {
    defer fmt.Println("This will not be printed")
    panic("Something went wrong")
}

7.3 recover

recover 用于恢复程序的控制权,通常与 defer 结合使用。

package main

import "fmt"

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from", r)
        }
    }()
    panic("Something went wrong")
}

示例代码

以下是一个综合示例,展示了函数的定义、参数传递、闭包、方法等特性:

package main

import "fmt"

// 定义一个函数
func add(a int, b int) int {
    return a + b
}

// 返回闭包函数
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x 
        return sum
    }
}

// 定义一个结构体
type Rectangle struct {
    Width, Height int
}

// 给结构体绑定方法
func (r Rectangle) Area() int {
    return r.Width * r.Height
}

func main() {
    // 调用函数
    result := add(3, 4)
    fmt.Println(result) // 输出: 7

    // 使用闭包
    pos, neg := adder(), adder()
    for i := 0; i < 5; i++ {
        fmt.Println(pos(i), neg(-2*i))
    }

    // 使用方法
    rect := Rectangle{Width: 10, Height: 5}
    fmt.Println(rect.Area()) // 输出: 50
}

通过以上教程和示例,你可以系统地了解和掌握Go语言中的各种函数特性。多加练习,能够更加熟练地运用这些特性编写高效的Go程序。

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://example.com/subject/article/87/

许可协议:署名-非商业性使用 4.0 国际许可协议