go中的函数

demo1:函数的几种定义方式

package main

import (
    "errors"
    "fmt"
)

/*
函数的用法
跟其他语言的区别:支持多个返回值


*/

//函数定义方法1
func add(a, b int) int {
    return a + b
}

//函数定义方法2
func add2(a, b int) (sun int) {
    sun = a + b
    return sun
}

//函数定义方法3:返回多个值
func div(a, b int) (int, error) {
    var err error
    var result int
    if b == 0 {
        err = errors.New("除数不能为0")
    } else {
        result = a / b
    }
    return result, err
}

func main() {
    res, err := div(12, 3)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(res)
    }

}

demo2: 参数传递的几种方式

package main

import "fmt"

/*
函数的用法
省略号参数用法1:
当有不定个值需要传入函数时,可以使用省略号。

省略号参数用法2:
用slice实现


*/

//方法1
func add3(a ...int) (sum int) {
    for _, v := range a {
        sum += v
    }
    return
}

//方法2
func add4(a []int) (sum int) {
    for _, v := range a {
        sum += v
    }
    a[0] = 9
    return
}

//方法3

func main() {
    /*
        方法1
        fmt.Println(add3(1, 2))
        fmt.Println(add3(1, 2, 3))
        fmt.Println(add3(1, 2, 3, 4))
    */

    /*
        方法2
        slice1 := []int{1, 2}
        fmt.Println(slice1)
        fmt.Println(add4(slice1))
        fmt.Println(slice1) //可以发现调用完函数后,slice1的值发生变化,因为传递的是引用类型的参数
    */
    arr := [...]int{1, 2, 3}
    fmt.Printf("%T", arr) // 数组类型
    fmt.Println()
    arr2 := []int{1, 2, 3}
    fmt.Printf("%T", arr2) // 切片类型

}

demo3:函数作为变量的值或参数

1、函数可以当做其他变量的值

2、函数可以作为参数传递给其他函数

package main

import "fmt"

/*
函数的用法
1、函数当做值赋值给其他变量

2、函数作为参数传递给其他函数

*/

type sub func(a, b int) int

func filter(score []int) []int {
    res := make([]int, 0)
    for _, v := range score {
        if v >= 60 {
            res = append(res, v)
        }
    }
    return res
}

//  将函数作为参数传递给其他函数
func filter2(score []int, f func(int2 int) bool) []int {
    res := make([]int, 0)
    for _, v := range score {
        if f(v) {
            res = append(res, v)
        }
    }
    return res
}

func main() {

    /*
        函数当做值赋值给其他变量实现
        res := func(a, b int) int {
            return a + b
        }(1, 2)
        fmt.Println(res)
        fmt.Println(res + 3)
    */

    var mySub = func(a, b int) int {
        return a - b
    }
    fmt.Println(mySub(1, 2))

    score := []int{10, 50, 70, 80, 95}
    fmt.Println(filter(score))

    //方法filter2调用
    fmt.Println(filter2(score, func(a int) bool {
        if a >= 60 {
            return true
        } else {
            return false
        }
    }))

}

defer使用

demo

package main

import "fmt"

/*
defer的使用
go语言中,没有try...expect...finally机制,是用defer机制处理
注意:defer之后只能是函数调用,不能是表达式。

一些应用的场景:
·文件的打开和关闭
·数据库连接的开启和关闭
·线程锁的获取和释放
·事务锁的添加和释放

defer的本质是注册了一个延迟函数,
*/

func f() int {
    x := 10
    defer func() {
        fmt.Println(x) //此处的x是外部的x,实际上就是闭包
    }()
    x++
    return 13
}

func main() {

    /*面对异常defer依然执行
    fmt.Println("test1")
    defer fmt.Println("defer test")
    panic("error")
    fmt.Println("test2")
    */

    /*
        多个defer语句执行顺序是逆序的,遵循先进先出原则
        fmt.Println("test")
        defer fmt.Println("defer test1")
        defer fmt.Println("defer test2")
        defer fmt.Println("defer test3")
    */

    /*
        最终只会输入结果:test1  因为defer执行时候的拷贝机制
        test := func() {
            fmt.Println("test1")
        }
        defer test()
        test = func() {
            fmt.Println("test2")
        }

    */

    /*
        下面这段最终输出结果为10而不是11,这跟拷贝机制有关
        x:=10
        defer func(a int) {
            fmt.Println(a)
        }(x)
        x++

        下面这段最终输出结果为11
        x := 10
        defer func(a *int) {
            fmt.Println(*a)
        }(&x)
        x++

        下面这段最终输出结果为11
        x := 10
        defer func() {		//匿名函数
            fmt.Println(x)
        }()
        x++
    */

    //调用f(),这里输出结果为11,13,说明defer是在return之前执行
    fmt.Println(f())
}

你可能感兴趣的:(go,golang,开发语言)