Golang中的关键字defer、:=、go func()怎么调用

发布时间:2023-04-28 11:24:00 作者:iii
来源:亿速云 阅读:149

Golang中的关键字defer、:=、go func()怎么调用

在Golang(Go语言)中,defer:=go func() 是三个非常常见且重要的关键字。它们分别用于延迟执行、变量声明和并发编程。本文将详细介绍这三个关键字的用法,并通过代码示例帮助读者更好地理解它们的工作原理。

1. defer 关键字

1.1 defer 的基本用法

defer 关键字用于延迟执行一个函数或方法调用。被 defer 修饰的语句会在当前函数返回之前执行,无论函数是正常返回还是发生了异常。

func main() {
    defer fmt.Println("World")
    fmt.Println("Hello")
}

输出结果:

Hello
World

在这个例子中,fmt.Println("World")defer 修饰,因此它会在 main 函数返回之前执行,即在 fmt.Println("Hello") 之后执行。

1.2 defer 的执行顺序

如果有多个 defer 语句,它们会按照后进先出(LIFO)的顺序执行。

func main() {
    defer fmt.Println("First")
    defer fmt.Println("Second")
    defer fmt.Println("Third")
    fmt.Println("Hello")
}

输出结果:

Hello
Third
Second
First

在这个例子中,defer 语句按照 ThirdSecondFirst 的顺序执行。

1.3 defer 与返回值

defer 语句可以访问和修改函数的返回值。

func main() {
    fmt.Println(double(2))
}

func double(x int) (result int) {
    defer func() {
        result *= 2
    }()
    return x
}

输出结果:

4

在这个例子中,defer 语句修改了 double 函数的返回值,使其翻倍。

1.4 defer 的常见用途

defer 常用于资源释放、解锁、关闭文件等操作,以确保这些操作在函数返回之前执行。

func readFile(filename string) (string, error) {
    file, err := os.Open(filename)
    if err != nil {
        return "", err
    }
    defer file.Close()

    content, err := ioutil.ReadAll(file)
    if err != nil {
        return "", err
    }

    return string(content), nil
}

在这个例子中,defer file.Close() 确保文件在函数返回之前被关闭,无论函数是否发生错误。

2. := 关键字

2.1 := 的基本用法

:= 是 Go 语言中的短变量声明语法,用于声明并初始化变量。它相当于 var 关键字加上赋值操作。

func main() {
    x := 42
    fmt.Println(x)
}

输出结果:

42

在这个例子中,x := 42 声明了一个整数变量 x 并将其初始化为 42

2.2 := 的注意事项

func main() {
    x, y := 1, 2
    fmt.Println(x, y)
}

输出结果:

1 2

在这个例子中,x, y := 1, 2 同时声明并初始化了两个变量 xy

2.3 :=var 的区别

:=var 都可以用于变量声明,但它们有一些区别:

func main() {
    var x int = 42
    y := 42
    fmt.Println(x, y)
}

输出结果:

42 42

在这个例子中,var x int = 42y := 42 都声明并初始化了一个整数变量,但它们的语法不同。

3. go func() 关键字

3.1 go func() 的基本用法

go func() 是 Go 语言中的并发编程语法,用于启动一个新的 goroutine。goroutine 是 Go 语言中的轻量级线程,由 Go 运行时管理。

func main() {
    go func() {
        fmt.Println("Hello from goroutine")
    }()
    fmt.Println("Hello from main")
    time.Sleep(time.Second) // 等待 goroutine 执行完毕
}

输出结果:

Hello from main
Hello from goroutine

在这个例子中,go func() { ... }() 启动了一个新的 goroutine,该 goroutine 会并发执行 fmt.Println("Hello from goroutine")

3.2 go func()sync.WaitGroup

由于 goroutine 是并发执行的,主 goroutine 可能会在子 goroutine 执行完毕之前退出。为了避免这种情况,可以使用 sync.WaitGroup 来等待所有 goroutine 执行完毕。

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Println("Hello from goroutine")
    }()
    fmt.Println("Hello from main")
    wg.Wait() // 等待 goroutine 执行完毕
}

输出结果:

Hello from main
Hello from goroutine

在这个例子中,sync.WaitGroup 用于等待 goroutine 执行完毕。wg.Add(1) 表示有一个 goroutine 需要等待,wg.Done() 表示 goroutine 执行完毕,wg.Wait() 会阻塞直到所有 goroutine 执行完毕。

3.3 go func() 与通道(channel)

goroutine 之间可以通过通道(channel)进行通信。通道是 Go 语言中的一种并发安全的数据结构,用于在 goroutine 之间传递数据。

func main() {
    ch := make(chan string)
    go func() {
        ch <- "Hello from goroutine"
    }()
    msg := <-ch
    fmt.Println(msg)
}

输出结果:

Hello from goroutine

在这个例子中,ch := make(chan string) 创建了一个字符串通道,ch <- "Hello from goroutine" 将数据发送到通道,msg := <-ch 从通道接收数据。

3.4 go func() 的常见用途

go func() 常用于并发执行任务、处理请求、并行计算等场景。

func main() {
    urls := []string{"https://example.com", "https://google.com", "https://github.com"}
    var wg sync.WaitGroup
    for _, url := range urls {
        wg.Add(1)
        go func(u string) {
            defer wg.Done()
            resp, err := http.Get(u)
            if err != nil {
                fmt.Println("Error:", err)
                return
            }
            fmt.Println("Response from", u, ":", resp.Status)
        }(url)
    }
    wg.Wait()
}

在这个例子中,go func(u string) { ... }(url) 启动了一个新的 goroutine 来并发获取每个 URL 的响应。

4. 总结

通过本文的介绍和示例代码,读者应该能够更好地理解和使用 defer:=go func() 这三个关键字。在实际开发中,合理使用这些关键字可以提高代码的可读性和性能。

推荐阅读:
  1. mgo指定字符串长度查找数据的案例分析
  2. golang会不会取代php

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

golang

上一篇:Goland字符串格式化样式中“\r“的作用是什么

下一篇:SpringBoot依赖管理源码分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》