12-函数

140 阅读3分钟

函数的定义

  • Go语言定义函数使用func关键字,具体格式如下:

func 函数名(参数)(返回) { 函数体 }

  • 函数名由字母、数字、下划线组成.但函数名的第一位不能是数字,在同一个包内,函数名也称不重名
  • 参数: 参数由 参数变量和参数变量的类型组成,多个参数之间使用,分隔
  • 返回值: 返回值由返回值变量和其变量类型组成,也可以只写返回值的类型,多个返回值必须用()包裹,并用,分隔
  • 函数体: 实现指定功能的代码块
  • 参数(a, b int) 等价于 (a int, b int): 适合同类型的简写

基本参数写法

  • go语言中没有默认参数
package main
import (
    "fmt"
)

func main() {
    sayHello()// 函数调用
    sayHelloByName("倩倩")
    sum := intSum(1, 2)
    fmt.Println(sum)
    sum1 := intSum2(1, 2, 3)
    fmt.Println(sum1)
    sum2 := intSum3(1, 2, 3)
    fmt.Println(sum2)
}

// 1.定义无参数和返回值的函数
func sayHello () {
    fmt.Println("hello func")
}

// 2.定义一个接收string类型的参数,无返回值
func sayHelloByName(name string) {
    fmt.Println("hello " + name)
}
// 3.带2个参数(int类型)值相加的函数
func intSum (x int, y int) int {
    sum := x + y
    return sum
}

// 4.函数接收可变参数 -> 类似js的扩展运算符 ...
func intSum2(a ...int) int{
    fmt.Println(a)// [2 2 3]
    fmt.Printf("%T\n", a)// []int int类型的切片
    sum := 0
    for _, v := range a {
        sum += v
    }
    return sum
}

// 5. 固定参数(调用必传)和可变参数同时出现时,可变参数放在最后
func intSum3(a int, b ...int) int{
    sum := a
    for _, v := range b {
        sum += v
    }

    return sum
}

image.png

返回值

  • go语言支持多返回值,不同的类型的返回
  • 返回值(a, b int) 等价于 (a int, b int): 适合同类型的简写
package main
import (
    "fmt"
)

func main() {
    weight, tall, age, sexWeight, sex := getInfo()
    fmt.Println(weight, tall, age, sexWeight, sex)
}

// 定义多个返回值的函数:录取个人身体参数信息
func getInfo () (float64, float64, int, int, string) {
    // 录入各项
    var name string
    fmt.Print("姓名:")
    fmt.Scanln(&name)

    var age int
    fmt.Print("年龄")
    fmt.Scanln(&age)

    sexWeight := 0
	
    var sex string = "男"
    fmt.Print("性别(男/女):")
    fmt.Scanln(&sex)

    var weight float64
    fmt.Print("体重(千克):")
    fmt.Scanln(&weight)

    var tall float64
    fmt.Print("身高(米):")
    fmt.Scanln(&tall)

    return weight, tall, age, sexWeight, sex
}

defer 语句

  • Go语言的defer语句会将其后面跟随的语句进行延迟处理,在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行
  • 由于defer的延迟调用特性,能非常方便的处理资源释放问题.比如资源清理、文件的关闭、解锁、记录时间等
package main
import (
    "fmt"
)

func main() {
    fmt.Println("start...")
    defer fmt.Println("defer1")
    defer fmt.Println("defer2")
    defer fmt.Println("defer3")
    fmt.Println("end...")
}

image.png

函数进阶

变量的作用域

全局变量

  • 定义在函数函数外的变量,它在程序整个运行周期内都有效.在函数中可以访问到全局的变量
  • 函数的外层是没法使用内层函数的内部变量
package main
import (
    "fmt"
)

// 全局作用域
var num int = 10

// 定义函数
func testGlobal() {
    fmt.Println("全局变量", num)

    num := 100
    fmt.Println("函数局部变量", num)// 100
}

func main() {
    testGlobal()
}

image.png

局部变量

  • 函数内部的变量
  • 语句块里面的变量
package main
import (
    "fmt"
)

func main() {
    for i := 0; i < 3; i++ {
        fmt.Println(i)
    }
    // 变量i此时只在for循环的语句块中生效
    // fmt.Println(i)
    t := test
    fmt.Printf("%T\n", t)// func()

    // 回调函数的使用
    num := calc(1, 2, add)
    fmt.Println(num)
}

func test() {
    fmt.Println("test")
}

func add(x, y int) int {
    return x + y
}

func calc(x, y int, op func(int, int) int) int {
    return op(x, y)
}

image.png