golang return省略用法说明

 更新时间:2020年12月16日 09:05:33   作者:david___  
这篇文章主要介绍了golang return省略用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

golang函数如果返回值定义了变量,return后边必须跟着表达式或者值

func main() {
 fmt.Println("-------", test())
}
func test() (n string) {
 n = "hello"
 return
}

如果没有定义变量,return必须显示地返回对象

func main() {
 fmt.Println("-------", test())
}
func test() string {
 n := "hello"
 return n
}

补充:Golang中defer、return、返回值之间执行顺序的坑

Go语言中延迟函数defer充当着 cry...catch 的重任,使用起来也非常简便,然而在实际应用中,很多gopher并没有真正搞明白defer、return和返回值之间的执行顺序,从而掉进坑中,今天我们就来揭开它的神秘面纱!

先来运行下面两段代码:

A. 无名返回值的情况

package main 
import (
 "fmt"
)
 
func main() {
 fmt.Println("return:", a()) // 打印结果为 return: 0
}
 
func a() int {
 var i int
 defer func() {
 i++
 fmt.Println("defer2:", i) // 打印结果为 defer: 2
 }()
 defer func() {
 i++
 fmt.Println("defer1:", i) // 打印结果为 defer: 1
 }()
 return i
}<br><br>

B. 有名返回值的情况

package main
 
import (
 "fmt"
)
 
func main() {
 fmt.Println("return:", b()) // 打印结果为 return: 2
}
 
func b() (i int) {
 defer func() {
 i++
 fmt.Println("defer2:", i) // 打印结果为 defer: 2
 }()
 defer func() {
 i++
 fmt.Println("defer1:", i) // 打印结果为 defer: 1
 }()
 return i // 或者直接 return 效果相同
}

先来假设出结论,帮助大家理解原因:

1、多个defer的执行顺序为“后进先出”;

2、defer、return、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中;接着defer开始执行一些收尾工作;最后函数携带当前返回值退出。

如何解释两种结果的不同:

上面两段代码的返回结果之所以不同,其实从上面第2条结论很好理解。

a()int 函数的返回值没有被提前声名,其值来自于其他变量的赋值,而defer中修改的也是其他变量,而非返回值本身,因此函数退出时返回值并没有被改变。

b()(i int) 函数的返回值被提前声名,也就意味着defer中是可以调用到真实返回值的,因此defer在return赋值返回值 i 之后,再一次地修改了 i 的值,最终函数退出后的返回值才会是defer修改过的值。

C. 下面我们再来看第三个例子,验证上面的结论:

package main 
import (
 "fmt"
)
 
func main() {
 fmt.Println("c return:", *(c())) // 打印结果为 c return: 2
}
 
func c() *int {
 var i int
 defer func() {
 i++
 fmt.Println("c defer2:", i) // 打印结果为 c defer: 2
 }()
 defer func() {
 i++
 fmt.Println("c defer1:", i) // 打印结果为 c defer: 1
 }()
 return &i
}

虽然 c()*int 的返回值没有被提前声明,但是由于 c()*int 的返回值是指针变量,那么在return将变量 i 的地址赋给返回值后,defer再次修改了 i 在内存中的实际值,因此函数退出时返回值虽然依旧是原来的指针地址,但是其指向的内存实际值已经被成功修改了。

即,我们假设的结论是正确的!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 盘点总结2023年Go并发库有哪些变化

    盘点总结2023年Go并发库有哪些变化

    这篇文章主要为大家介绍了2023年Go并发库的变化盘点总结,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • golang如何实现抓取IP地址的蜘蛛程序详解

    golang如何实现抓取IP地址的蜘蛛程序详解

    这篇文章主要给大家介绍了关于利用golang如何实现抓取IP地址的蜘蛛程序的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • go语言interface接口继承多态示例及定义解析

    go语言interface接口继承多态示例及定义解析

    这篇文章主要为大家介绍了go语言interface接口继承多态示例及定义解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go语言轻量级高性能嵌入式规则引擎RuleGo使用详解

    Go语言轻量级高性能嵌入式规则引擎RuleGo使用详解

    这篇文章主要为大家介绍了Go语言轻量级高性能嵌入式规则引擎RuleGo使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Systemd集成Golang二进制程序的方法

    Systemd集成Golang二进制程序的方法

    这篇文章主要介绍了Systemd集成Golang二进制程序的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-10-10
  • vim配置go语言语法高亮问题的解决方法

    vim配置go语言语法高亮问题的解决方法

    vim配置go语言语法高亮的问题已经遇到过好几次了,每次都是找不到答案,今天小编给大家带来了vim配置go语言语法高亮问题的解决方法,感兴趣的朋友一起看看吧
    2018-01-01
  • Go 代码块作用域变量遮蔽问题解析

    Go 代码块作用域变量遮蔽问题解析

    这篇文章主要为大家介绍了Go 代码块作用域变量遮蔽问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • GoFrame基于性能测试得知grpool使用场景

    GoFrame基于性能测试得知grpool使用场景

    这篇文章主要为大家介绍了GoFrame基于性能测试得知grpool使用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 一文详解如何在Golang中实现JWT认证与授权

    一文详解如何在Golang中实现JWT认证与授权

    在现代Web应用中,安全性是一个非常重要的课题,JWT作为一种常用的认证与授权机制,已被广泛应用于各种系统中,下面我们就来看看如何在Golang中实现JWT认证与授权吧
    2025-03-03
  • 轻松入门:使用Golang开发跨平台GUI应用

    轻松入门:使用Golang开发跨平台GUI应用

    Golang是一种强大的编程语言,它的并发性和高性能使其成为开发GUI桌面应用的理想选择,Golang提供了丰富的标准库和第三方库,可以轻松地创建跨平台的GUI应用程序,通过使用Golang的GUI库,开发人员可以快速构建具有丰富用户界面和交互功能的应用程序,需要的朋友可以参考下
    2023-10-10

最新评论