Golang——函数func

Cici冬雪 · · 1451 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

函数是执行特定公开、可复用的代码块,包括函数、匿名函数、闭包。可作为变量、返回值、参数等。

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

函数名:字母、数字、下划线组成,第一个字母不能是数字;同一个包内,函数名也不能重名;
返回值:可返回多个返回值,必须用()包裹,并用,分隔

函数定义与使用

func testOne(){
    fmt.Println("Hello")
}

func testTwo(x int){
    fmt.Println(x)
}

//多个同类型的参数,可省略前面的类型
func testThree(x, y int){
    fmt.Println(x, y)
}

func testSum(x int, y int)int{
    ret := x + y
    return ret
} 

func testSum2(x int, y int)(ret int){
    ret = x + y
    return 
} 

//可变参数,在函数体中是切片类型
//固定参数和可变参数一起出现时候,可变参数必须放到最后
//go语言中没有默认参数
func testSum3(a int, x ...int)int{
    fmt.Printf("tyep:%T,content:%v\n", a, a)
    fmt.Printf("tyep:%T,content:%v\n", x, x)
    sum := 0
    for _, value := range x {
        sum += value
        // sum = testSum2(sum, value)
    }
    return sum
} 


//多个返回值情况,必须用括号包起来
//多个返回值,也支持参数简写
func calc(a, b int)(sum, sub int){
    sum = a + b
    sub = a - b
    return 
}


func main() {
    
    testOne()

    testTwo(2)

    testThree(3, 3)

    fmt.Println(testSum(1, 1))

    fmt.Println(testSum2(2, 2))

    sum1 := testSum3(1, 2, 3, 4, 5);
    fmt.Println(sum1)

    sum2 := testSum3(1, 2, 3, 4);
    fmt.Println(sum2)

    sum3 := testSum3(1);
    fmt.Println(sum3)

    sum, sub := calc(100, 200)
    fmt.Println(sum, sub)

} 

defer语句

将其后面跟随的语句进行延迟处理,在defer归属的函数即将返回时,讲延迟处理的语句按照defer定义的逆序进行执行(先被defer的语句最后执行,最后被defer语句,最先被执行)。
defer语句非常方便处理资源释放问题,比如资源清理、文件关闭、解锁及记录时间等。

//defer 延迟执行
func main() {
    fmt.Println("start")
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("end")
} 

输出
start
end
3
2
1

作用域

  • 函数内部可以访问全局变量,如果函数内部定义同名的局部变量,先取用局部变量;
  • 外层不能访问函数的内部变量(局部变量);
  • 外层访问不到内部for、if、switch语句块中的变量;
//定义全局变量
var num = 10

func test(){
    fmt.Println("全局变量", num)
    num := 20
    fmt.Println("局部变量", num)
}

func main() {
    test()

    fmt.Println("全局变量", num)
} 
输出
全局变量 10
局部变量 20
全局变量 10

函数作为变量

//定义全局变量
var num = 10

func test(){
    fmt.Println("全局变量", num)
    num := 20
    fmt.Println("局部变量", num)
}

func main() {
    //函数作为变量
    abc := test
    fmt.Printf("%T\n", abc)
    //调用
    abc() 
} 
输出
func()
全局变量 10
局部变量 20

函数作为参数

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

func sub(x, y int) int {
    return x - y
}

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

func main() {
    add := calc(100, 200, add)
    fmt.Println(add)

    sub := calc(100, 200, sub)
    fmt.Println(sub)
} 

匿名函数

没有函数名的函数

func(参数)(返回值){
    函数体
}
func main() {
    //匿名函数赋值给变量
    test := func(){
        fmt.Println("haha")
    }
    test()

    //匿名函数直接使用
    func(){
        fmt.Println("hihi")
    }() 
}

闭包

闭包指的是一个函数和与其相关的引用环境组合而成的实体,即闭包=函数+引用环境

//函数返回值是函数
func a() func() {
    name := "lv"
    return func(){
        fmt.Println("haha", name)
    }
}

func b(name string) func() {
    return func(){
        fmt.Println("haha", name)
    }
}

func main() {
    //闭包 = 函数 + 外层变量的引用
    r := a()
    r() //相当于执行了a函数内部的匿名函数

    c := b("c")
    c()
}

常用内置函数

内置函数 介绍
close 主要是用来关闭channel
len 求长度,例如string、array、slice、map、channel
new 主要分配值类型内存,例如 int、struct、string、array等,返回 的是指针
make 主要分配引用类型的内存,比如chan、map、slice
append 追加元素到array、slice中
panic和recover 用来错误处理

Go(1.12)没有异常处理,用panicrecover

  • recover必须搭配defer使用
  • defer一定要在可能引发panic的语句之前定义
func a(){
    fmt.Println("func a")
}

func b(){
    defer func(){
        err := recover()
        if err != nil {
            panic("func b error")
        }
    }()
    panic("panic in b")
}

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

func main() {
    a()
    b()  //程序崩溃
    c()
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:Cici冬雪

查看原文:Golang——函数func

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1451 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传