• 周五. 9月 30th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Go开发之路 — 函数详解

admin

11月 28, 2021

声明语法

func 函数名 (参数列表) [(返回值列表)] {}

Golang函数特点

a. 不支持重载,一个包不能有两个名字一样的函数
b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
c. 匿名函数
d. 多返回值

函数的参数传递方式

值传递

引用传递

注意1:
无论是值传递,还是引用传递,传递给函数的都是变量的副本, 不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址 拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能 越低。
注意2:
map、slice、chan、指针、interface默认以引用的方式传递

/*
package main

import "fmt"

func modify(a int) {
    a = 100
}

func main(){
    a := 8
    fmt.Println(a)
    modify(a)
    fmt.Println(a)
}
*/
// 修改上面的程序, 使其正确

package main

import "fmt"

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

func main(){
    a := 8
    fmt.Println(a)
    modify(&a)
    fmt.Println(a)
}

练习 13

命名返回值的名字

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

_标识符, 用来忽略返回值

func calc(a, b int) (sum int, avg int) {
        sum = a + b
        avg = (a +b)/2
        return
}
func main() {
      sum, _ := calc(100, 200)
}

可变参数

func add(arg…int) int {    // 0个或多个参数

}
func add(i int, arg…int) int {    // 1个或多个参数

}
func add(i int, j int, arg…int) int {    // 2个或多个参数

}
注意:
其中arg是一个slice,我们可以通过arg[index]依次访问所有参数
通过len(arg)来判断传递参数的个数

// 写一个函数add, 支持一个或多个int相加, 并返回相加结果

package main

import "fmt"

func add(x int, arg...int) int{
    var sum int = x
    for i := 0; i < len(arg); i++ {
        sum += arg[i]
    }
    return sum
}

func main(){
    res := add(2, 2)
    fmt.Println(res)
}

练习14

// 写一个函数concat, 支持一个或者多个string相拼接, 并返回结果

package main

import "fmt"

func concat(str string, arg...string)(res string){
    res = str
    for i := 0; i < len(arg); i++ {
        res += arg[i]
    }
    return
}

func main(){
    res := concat("plm", "asd")
    fmt.Println(res)
}

练习 15

defer的用途

1. 当函数返回时,执行defer语句。因此,可以用来做资源清理
2. 多个defer语句,按 先进后出 的方式执行
3. defer语句中的变量,在defer声明时就决定了

应用:

    1. 关闭文件句柄

func read(){
    file := open(filename)
    defer file.Close()

    //文件操作

}

    2. 锁资源释放

func read() {
    mc.Lock()
    defer mc.Unlock()
    //其他操作
}

    3. 数据库连接释放

func read() {
    conn := openDatabase()
    defer conn.Close()
    //其他操作
}

发表回复

您的电子邮箱地址不会被公开。