golang return省略用法說(shuō)明
golang函數(shù)如果返回值定義了變量,return后邊必須跟著表達(dá)式或者值
func main() {
fmt.Println("-------", test())
}
func test() (n string) {
n = "hello"
return
}
如果沒(méi)有定義變量,return必須顯示地返回對(duì)象
func main() {
fmt.Println("-------", test())
}
func test() string {
n := "hello"
return n
}
補(bǔ)充:Golang中defer、return、返回值之間執(zhí)行順序的坑
Go語(yǔ)言中延遲函數(shù)defer充當(dāng)著 cry...catch 的重任,使用起來(lái)也非常簡(jiǎn)便,然而在實(shí)際應(yīng)用中,很多gopher并沒(méi)有真正搞明白defer、return和返回值之間的執(zhí)行順序,從而掉進(jìn)坑中,今天我們就來(lái)揭開(kāi)它的神秘面紗!
先來(lái)運(yùn)行下面兩段代碼:
A. 無(wú)名返回值的情況
package main
import (
"fmt"
)
func main() {
fmt.Println("return:", a()) // 打印結(jié)果為 return: 0
}
func a() int {
var i int
defer func() {
i++
fmt.Println("defer2:", i) // 打印結(jié)果為 defer: 2
}()
defer func() {
i++
fmt.Println("defer1:", i) // 打印結(jié)果為 defer: 1
}()
return i
}<br><br>
B. 有名返回值的情況
package main
import (
"fmt"
)
func main() {
fmt.Println("return:", b()) // 打印結(jié)果為 return: 2
}
func b() (i int) {
defer func() {
i++
fmt.Println("defer2:", i) // 打印結(jié)果為 defer: 2
}()
defer func() {
i++
fmt.Println("defer1:", i) // 打印結(jié)果為 defer: 1
}()
return i // 或者直接 return 效果相同
}
先來(lái)假設(shè)出結(jié)論,幫助大家理解原因:
1、多個(gè)defer的執(zhí)行順序?yàn)椤昂筮M(jìn)先出”;
2、defer、return、返回值三者的執(zhí)行邏輯應(yīng)該是:return最先執(zhí)行,return負(fù)責(zé)將結(jié)果寫(xiě)入返回值中;接著defer開(kāi)始執(zhí)行一些收尾工作;最后函數(shù)攜帶當(dāng)前返回值退出。
如何解釋兩種結(jié)果的不同:
上面兩段代碼的返回結(jié)果之所以不同,其實(shí)從上面第2條結(jié)論很好理解。
a()int 函數(shù)的返回值沒(méi)有被提前聲名,其值來(lái)自于其他變量的賦值,而defer中修改的也是其他變量,而非返回值本身,因此函數(shù)退出時(shí)返回值并沒(méi)有被改變。
b()(i int) 函數(shù)的返回值被提前聲名,也就意味著defer中是可以調(diào)用到真實(shí)返回值的,因此defer在return賦值返回值 i 之后,再一次地修改了 i 的值,最終函數(shù)退出后的返回值才會(huì)是defer修改過(guò)的值。
C. 下面我們?cè)賮?lái)看第三個(gè)例子,驗(yàn)證上面的結(jié)論:
package main
import (
"fmt"
)
func main() {
fmt.Println("c return:", *(c())) // 打印結(jié)果為 c return: 2
}
func c() *int {
var i int
defer func() {
i++
fmt.Println("c defer2:", i) // 打印結(jié)果為 c defer: 2
}()
defer func() {
i++
fmt.Println("c defer1:", i) // 打印結(jié)果為 c defer: 1
}()
return &i
}
雖然 c()*int 的返回值沒(méi)有被提前聲明,但是由于 c()*int 的返回值是指針變量,那么在return將變量 i 的地址賦給返回值后,defer再次修改了 i 在內(nèi)存中的實(shí)際值,因此函數(shù)退出時(shí)返回值雖然依舊是原來(lái)的指針地址,但是其指向的內(nèi)存實(shí)際值已經(jīng)被成功修改了。
即,我們假設(shè)的結(jié)論是正確的!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
盤(pán)點(diǎn)總結(jié)2023年Go并發(fā)庫(kù)有哪些變化
這篇文章主要為大家介紹了2023年Go并發(fā)庫(kù)的變化盤(pán)點(diǎn)總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
golang如何實(shí)現(xiàn)抓取IP地址的蜘蛛程序詳解
這篇文章主要給大家介紹了關(guān)于利用golang如何實(shí)現(xiàn)抓取IP地址的蜘蛛程序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
go語(yǔ)言interface接口繼承多態(tài)示例及定義解析
這篇文章主要為大家介紹了go語(yǔ)言interface接口繼承多態(tài)示例及定義解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Go語(yǔ)言輕量級(jí)高性能嵌入式規(guī)則引擎RuleGo使用詳解
這篇文章主要為大家介紹了Go語(yǔ)言輕量級(jí)高性能嵌入式規(guī)則引擎RuleGo使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
vim配置go語(yǔ)言語(yǔ)法高亮問(wèn)題的解決方法
vim配置go語(yǔ)言語(yǔ)法高亮的問(wèn)題已經(jīng)遇到過(guò)好幾次了,每次都是找不到答案,今天小編給大家?guī)?lái)了vim配置go語(yǔ)言語(yǔ)法高亮問(wèn)題的解決方法,感興趣的朋友一起看看吧2018-01-01
GoFrame基于性能測(cè)試得知grpool使用場(chǎng)景
這篇文章主要為大家介紹了GoFrame基于性能測(cè)試得知grpool使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
一文詳解如何在Golang中實(shí)現(xiàn)JWT認(rèn)證與授權(quán)
在現(xiàn)代Web應(yīng)用中,安全性是一個(gè)非常重要的課題,JWT作為一種常用的認(rèn)證與授權(quán)機(jī)制,已被廣泛應(yīng)用于各種系統(tǒng)中,下面我們就來(lái)看看如何在Golang中實(shí)現(xiàn)JWT認(rèn)證與授權(quán)吧2025-03-03
輕松入門(mén):使用Golang開(kāi)發(fā)跨平臺(tái)GUI應(yīng)用
Golang是一種強(qiáng)大的編程語(yǔ)言,它的并發(fā)性和高性能使其成為開(kāi)發(fā)GUI桌面應(yīng)用的理想選擇,Golang提供了豐富的標(biāo)準(zhǔn)庫(kù)和第三方庫(kù),可以輕松地創(chuàng)建跨平臺(tái)的GUI應(yīng)用程序,通過(guò)使用Golang的GUI庫(kù),開(kāi)發(fā)人員可以快速構(gòu)建具有豐富用戶界面和交互功能的應(yīng)用程序,需要的朋友可以參考下2023-10-10

