为什么需要函数

  • 做一件事通常需要很多步骤,每个步骤可以分解为独立的函数,这些函数以后可能会复用到。

函数声明

  • Go 在标准库文档中列出了标准库每个包中声明的函数。
    例如:
    • rand 包的 Intn:func Intn(n int) int
    • 它的用法:num := rand.Intn(10)
  • 使用 func 关键字声明函数

函数 - 图1

  • 在 Go 里,大写字母开头的函数、变量或其它标识符都会被导出,对其它包可用。
  • 小写字母开头的就不行。
  • 形式参数:parameter
  • 实际参数:argument

多个参数

  • 函数的参数可以是多个:
    • func Unix(sec int64, nsec int64) Time
    • 调用:future := time.Unix(12622780800, 0)
  • 函数声明时,如果多个形参类型相同,那么该类型只写一次即可:
    • func Unix(sec int64, nsec int64) Time
    • func Unix(sec, nsec int64) Time
  • 这种简化是可选的。

返回多个值

  • Go 的函数可以返回多个值:
    • countdown, err := strconv.Atoi(“10”)
  • 该函数的声明如下:
    • func Atoi(s string) (i int, err error)
  • 函数的多个返回值需要用括号括起来,每个返回值名字在前,类型在后。声明函数时可以把名字去掉,只保留类型:
    • func Atoi(s string) (int, error)

可变参数函数

  • Println 是一个特殊的函数,它可以接收一个、二个甚至多个参数,参数类型还可以不同:
    • fmt.Println(“Hello, playground”)
    • fmt.Println(186, “seconds”)
  • Println 的声明是这样的:
    • func Println(a …interface{}) (n int, err error)
    • … 表示函数的参数的数量是可变的。
    • 参数 a 的类型为 interface{},是一个空接口。
  • … 和空接口组合到一起就可以接受任意数量、类型的参数了

编写函数

函数 - 图2

  • 函数按值传递参数
  • 同一个包中声明的函数在调用彼此时不需要加上包名。

作业题

  • 修改这段代码:
    • 复用 kelvinToCelsius 函数,将 233ºK 转化为 ℃。
    • 编写 celsiusToFahrenheit 函数,它可将摄氏度转化为华氏度。
      • 公式为 (c x 9.0/5.0) + 32.0
    • 编写 kelvinToFahrenheit 函数,看看它能否将 0ºK 转化为约 -459.67℉

函数 - 图3

  1. package main
  2. import "fmt"
  3. func kelvinToCelsius(k float64) float64 {
  4. return k - 273.15
  5. }
  6. func celsiusToFahrenheit(c float64) float64 {
  7. return (c * 9.0 / 5.0) + 32.0
  8. }
  9. func kelvinToFahrenheit(k float64) float64 {
  10. return celsiusToFahrenheit(kelvinToCelsius(k))
  11. }
  12. func main() {
  13. fmt.Printf("233º K is %.2fº C\n", kelvinToCelsius(233))
  14. fmt.Printf("0º K is %.2fº F\n", kelvinToFahrenheit(0))
  15. }