答案
例如:
1234567
891011
1213
1415
1617
18
func test() int ()這個例子中,可以看到 defer 的執行順序:後進先出。但是返回值並沒有被修改,這是由於 go 的返回機制決定的,執行 return 語句後,go 會建立乙個臨時變數儲存返回值,因此,defer 語句修改了區域性變數 i,並沒有修改返回值。那如果是有名的返回值呢?defer func() ()
return i
}func main()
// defer2
// defer1
// return 0
1234567
891011
1213
14
func test() (i int) ()這個例子中,返回值被修改了。對於有名返回值的函式,執行 return 語句時,並不會再建立臨時變數儲存,因此,defer 語句修改了 i,即對返回值產生了影響return i
}func main()
// defer2
// return 1
再看下面乙個題
import "fmt"輸出如下var name string = "go"
func myfunc() string ()
fmt.printf("myfunc 函式裡的name:%s\n", name)
return name
}func main()
myfunc 函式裡的name:go來一起理解一下這段**,第一行很直觀,name 此時還是全域性變數,值還是gomain 函式裡的name: python
main 函式裡的myname: go
第二行也不難理解,在 defer 裡改變了這個全域性變數,此時name的值已經變成了 python
重點在第三行,為什麼輸出的是 go ?
解釋只有乙個,那就是 defer 是return 後才呼叫的。所以在執行 defer 前,myname 已經被賦值成 go 了
答案答案答案答案答案答案專題:go 語言面試題
本文發表於 2020-09-04,最後修改於 2022-02-25。
本站永久網域名稱「 geektutu.com 」,也可搜尋「 極客兔兔 」找到我。
go2 新特性簡明教程
發表於2019-08-15, 閱讀約17分鐘
tensorflow 2 中文文件 - 過擬合與欠擬合
發表於2019-07-12, 閱讀約19分鐘
pandas 資料處理(三) - cheat sheet 中文版
發表於2019-06-16, 閱讀約4分鐘
#關於我 (9)
#go (48)
#百寶箱 (2)
#cheat sheet (1)
#go語言高效能程式設計 (20)
#友鏈 (1)
#pandas (3)
#機器學習 (9)
#python (10)
#rust (1)
#tensorflow (9)
#mnist (5)
#強化學習 (3)
#openai gym (4)
#dqn (1)
#q-learning (1)
#cnn (1)
#tensorflow 2 (10)
#官方文件 (10)
未登入使用者
預覽使用 github 登入
發表於超過 1 年前
新手有兩個問題想請教下:
**中rune("go語言")
意思是使用rune
強制轉換型別是吧?
其中**塊中的第10行
b = b[:len(a)]
這麼操作的目的是什麼?保證陣列切片一樣長嗎?
發表於超過 1 年前
@lisgroup
第乙個問題,你的理解是對的,字串型別轉換為 rune 切片型別。
第二個問題,這種寫法是為了優化邊界檢查從而提公升執行時效率的。在go語言中稱之為bounds check elimination
,簡稱為 bce。簡言解釋下,如果沒有這一句,在執行時,go 語言每次都會對 b[i] 做邊界檢查,看看是否越界了,如果越界了,就 panic。但是如果加上這一句,go語言在編譯時,能夠做一些簡單的靜態分析,發現 b[i] 是不可能越界的,編譯時就能將沒必要的邊界檢查給優化了,那麼執行時,就不會對 b[i] 做邊界檢查,從而提公升執行時效率。
這篇文章提供了更多的示例,幫助理解。bounds check elimination - go101.org
發表於超過 1 年前
_ = b[:len(a)]
發表於超過 1 年前
@givetimetolife 我覺得這種寫法應該也是ok的,go 的切片底層對應的陣列是一樣的,切片只是改變指標的位置,這一步檢查幾乎是沒有損耗的。
發表於大約 1 年前
2. q13 如何判斷 2 個字串切片(slice) 是相等的?
針對這個中的b = b[:len(a)]
,使用go 1.15.6
編譯,已經沒有效果了,在len判斷
的時候就已經做了優化
發表於大約 1 年前
@zzhaolei 感謝指出問題,新版本將b = b[:len(a)]
去掉後,也不會產生邊界檢查(bounds check)了。
是否產生邊界檢查,可以用下面的命令驗證。
go build -gcflags="-d=ssa/check_bce/debug=1" main.go例如針對下面的例子,如果 s[2] 沒有越界,那麼 s[1] 和 s[0] 肯定是合法,因此只需要對 s[2] 做一次邊界檢查即可:
package mainfunc f(s int)
func main() {}
go build -gcflags="-d=ssa/check_bce/debug=1" main.goyinhuanyi—— 博主,group的getfrompeer方法返回的byteview必須是指標,好像寫錯了 ``` func (g *group) getfrompeer(peer peergetter, key string) (*byteview, error) , err } return &byteview, nil } ```# command-line-arguments
./main.go:4:7: found isinbounds
有返回值和無返回值函式
前面在定義函式時,有些函式使用了return語句,有些函式沒有使用return語句,使用return語句與不使用return語句有什麼區別呢?由前面的章節我們知道,若定義函式時沒有使用return語句,則預設返回乙個none。要返回乙個none,可以只寫乙個return,但要返回具體的數值,就需要在...
返回值優化
通過傳值方式返回要建立新物件時,應注意使用的形式,例如在operator return integer left.l right.l 咋看起來這像是乙個 對乙個建構函式的呼叫 其實並非如此。這是臨時物件語法,它是在說 建立乙個臨時integer物件並返回它 據此我們可能認為如果建立乙個有名字的區域性...
返回值優化
返回值優化,是一種屬於編譯器的技術,它通過轉換源 和物件的建立來加快源 的執行速度。rvo return value optimization。class complex 複數 complex const complex a real a.real imag a.imag complex opera...