06.函数

Go 语言中的函数是代码组织和复用的基础,函数的定义和调用非常简单明了。下面是 Go 语言中函数的基础语法和一些关键概念:

函数的定义

在 Go 语言中,函数的定义包括函数名、参数列表、返回值类型和函数体。语法格式如下:

func 函数名(参数列表) 返回值类型 {
    函数体
}

 

示例

下面是一个简单的函数示例,该函数接收两个整数参数并返回它们的和:

package main

import "fmt"

// 定义一个函数 add,接收两个整数参数 a 和 b,返回它们的和
func add(a int, b int) int {
    return a + b
}

func main() {
    // 调用 add 函数,并将返回值赋给 sum
    sum := add(3, 4)
    fmt.Println("3 + 4 =", sum) // 输出:3 + 4 = 7
}

 

参数和返回值

  • 多个参数:如果参数列表中有多个参数,它们之间用逗号分隔。如果多个参数的类型相同,可以省略重复的类型声明:

    func add(a, b int) int {
        return a + b
    }

     

  • 多个返回值:Go 语言支持函数返回多个值:

    func swap(x, y string) (string, string) {
        return y, x
    }
    
    func main() {
        a, b := swap("hello", "world")
        fmt.Println(a, b) // 输出:world hello
    }

     

命名返回值

函数的返回值可以命名,这样可以在函数体中直接使用这些变量,并在函数末尾使用 return 语句返回:

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

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

 

空白标识符 _

如果函数返回多个值,但你不需要使用其中的某些值,可以使用空白标识符 _ 忽略它们:

func foo() (int, int, int) {
    return 1, 2, 3
}

func main() {
    a, _, c := foo()
    fmt.Println(a, c) // 输出:1 3
}

 

可变参数

Go 语言支持可变参数函数,即函数参数的个数可以是可变的。语法是使用省略号 ... 表示可变参数:

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(1, 2, 3, 4)) // 输出:10
}

 

小结

  • 函数是 Go 语言中代码复用的基本单位。
  • 函数可以有多个参数和返回值。
  • 函数参数和返回值可以命名,增加代码的可读性。
  • 可变参数函数可以接收任意数量的参数。

通过理解这些基本语法,可以在 Go 语言中更有效地定义和使用函数。

课程案例

实现加减乘除

package main

import "fmt"

func eval(a, b int, op string) int {
    switch op {
    case "+":
        return a + b
    case "-":
        return a - b
    case "*":
        return a * b
    case "/":
        return a / b
    default:
        panic("unsupported operation" + op)
    }
}
func main() {
    fmt.Println(eval(1, 2, "+"))
}

运行结果:

 取余操作

func div(a, b int) (int, int) {
    return a / b, a % b
}
func main() {
    fmt.Println(div(10, 2))
    fmt.Println(div(10, 3))
}

 写法二:

package main

import "fmt"

func div(a, b int) (quotient, remainder int) {
    return a / b, a % b
}
func main() {
    quotient, remainder := div(10, 3)
    fmt.Println(quotient, remainder)
}

两个返回值只想要一个的情况:

    case "/":
        quotient, _ := div(a, b)
        return quotient

处理非法制报错操作

package main

import "fmt"

func eval(a, b int, op string) (int, error) {
    switch op {
    case "+":
        return a + b, nil
    case "-":
        return a - b, nil
    case "*":
        return a * b, nil
    case "/":
        quotient, _ := div(a, b)
        return quotient, nil
    default:
        //会中断执行
        //panic("unsupported operation" + op)
        return 0, fmt.Errorf("unsupported operation: %s", op)
    }
}
func div(a, b int) (quotient, remainder int) {
    return a / b, a % b
}
func main() {
  if result, err := eval(1, 2, "x"); err != nil {
  fmt.Println("Error:", err)
  } else {
    fmt.Println(result)
  }
}

运行结果:

 

nil 是一个预定义的标识符,表示函数调用成功且没有错误发生。具体来说,nilerror 类型的零值,表示没有错误。让我们详细解释一下 nil 在你的代码中的作用。

nileval 函数中的作用

定义了一个名为 eval 的函数,这个函数接受两个整数 ab 以及一个字符串 op(表示操作符),然后根据操作符执行相应的算术运算。函数返回一个整数结果和一个 error 类型的值。

在这个函数中:

  1. return a + b, nil 等等:

    • 当操作符是 "+""-""*""/" 时,函数返回计算结果和 nil。这里的 nil 表示没有错误发生。例如,return a + b, nil 意味着加法操作成功,没有错误。
  2. return 0, fmt.Errorf("unsupported operation: %s", op):

    • 如果操作符不在支持的范围内(即既不是 "+""-""*" 也不是 "/"),函数返回 0 和一个 error 类型的值,表示发生了不支持的操作错误。fmt.Errorf 创建一个带有格式化字符串的 error 对象。

nil 的意义

在 Go 语言中,函数通常使用返回值 error 来表示函数是否成功执行。如果 error 返回 nil,则表示函数成功执行,没有发生错误。如果 error 返回非 nil 的值,则表示函数执行过程中发生了错误。通过这种方式,Go 语言避免了使用异常处理错误。

运算方法重写案例

package main

import (
    "fmt"
    "math"
    "reflect"
    "runtime"
)


func apply(op func(int, int) int, a, b int) int {
    p := reflect.ValueOf(op).Pointer()
    opName := runtime.FuncForPC(p).Name()
    fmt.Printf("Calling function %s with arguments"+"(%d, %d)\n", opName, a, b)
    return op(a, b)
}
func pow(a, b int) int {
    return int(math.Pow(float64(a), float64(b)))
}

func main() {
    fmt.Println(apply(pow, 3, 4))
}

 

posted @ 2024-07-07 02:46  JJJhr  阅读(3)  评论(0编辑  收藏  举报