Golang 斷言與閉包使用解析
1. Go斷言的使用
Go中的斷言用于判斷變量的類型,其使用形式如下所示:
value, ok := x.(T)
上面的代碼是判斷x是否為T類型的變量:
- 如果 T 的某個(gè)具體的類型,斷言會(huì)檢查 x 是否為該類型,如果是的話買就返回 x 以及一個(gè)布爾值
true,反之返回一個(gè)false - 如果 T 是接口類型,類型斷言會(huì)檢查 x 的動(dòng)態(tài)類型是否滿足 T。如果檢查成功,返回值是一個(gè)類型為 T 的接口值,以及一個(gè)布爾值
true,反之返回一個(gè)false - 我們也可以不接受返回的布爾值,在這種情況下,如果斷言失敗,會(huì)直接
panic,所以非常不推薦這種處理方式
另外,斷言和可以與switch配合使用
switch a.(type) {
case int:
fmt.Println("the type of a is int")
case string:
fmt.Println("the type of a is string")
case float64:
fmt.Println("the type of a is float")
default:
fmt.Println("unknown type")
}2. 閉包的解讀
閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。
概念上說(shuō)起來(lái)有些抽象,下面我們以一個(gè)具體的例子來(lái)理解。
func foo1(x int) func() {
return func() {
x = x + 1
fmt.Printf("foo2 val = %d\n", x)
}
}
f1 := foo1(1)
f1() // 2
f1() // 3在上面的例子中,f1() 與他的變量x(值為1)共同組成了一個(gè)閉包,每次調(diào)用f1(),x的值就會(huì)+1并且打印。
從某種意義上來(lái)說(shuō),閉包延長(zhǎng)了變量的生命周期(棧上分配改為了堆上分配)。
2.1 指針傳遞
func foo2(x *int) func() {
return func() {
*x = *x + 1
fmt.Printf("foo2 val = %d\n", *x)
}
}
x := 1
f1 := foo2(&x)
f2 := foo2(&x)
f1() // 2
f2() // 3通過(guò)第一個(gè)例子,我們知道,函數(shù)以及其環(huán)境(傳入的變量)組成了閉包,這個(gè)時(shí)候,如果傳入的是一個(gè)指針,那么就會(huì)存在多個(gè)閉包共用一個(gè)變量的情況。
2.2 延遲綁定
閉包的延遲綁定,通俗地說(shuō),就是閉包的函數(shù)在第一次調(diào)用的時(shí)候才會(huì)與環(huán)境的變量進(jìn)行綁定,我們依然以上面提到的兩個(gè)函數(shù)為例子:
func foo1(x int) func() {
return func() {
x = x + 1
fmt.Printf("foo2 val = %d\n", x)
}
}
func foo2(x *int) func() {
return func() {
*x = *x + 1
fmt.Printf("foo2 val = %d\n", *x)
}
}
x := 1
f1 := foo1(x)
f2 := foo2(&x)
f2() // 2
f1() // 3- 我們創(chuàng)建了f1與f2兩個(gè)閉包函數(shù),以及變量 x 的值為1
- 在f1與f2創(chuàng)建的時(shí)候,變量并沒有與函數(shù)綁定
- 第一次調(diào)用f2()時(shí),&x與其綁定,x的值+1,變?yōu)?
- 第一次調(diào)用f1()時(shí),x與其綁定,這時(shí)x已經(jīng)變?yōu)?了,再+1,所以變?yōu)?
2.3 Go Routine的延遲綁定
我們?cè)谝粋€(gè)函數(shù)中啟動(dòng) Go Routine 調(diào)用另一個(gè)函數(shù):
func show(v interface{}) {
fmt.Printf("foo4 val = %v\n", v)
}
func foo4() {
values := []int{1, 2, 3, 5}
for _, val := range values {
go show(val)
}
}
?
foo4()
//foo3 val = 2
//foo3 val = 3
//foo3 val = 1
//foo3 val = 5因?yàn)镚o Routine的執(zhí)行順序是隨機(jī)并行的,因此執(zhí)行多次foo4()輸出的順序不一行相同,但是一定打印了“1,2,3,5”各個(gè)元素。
但是,如果我們以匿名函數(shù)的形式嘗試復(fù)現(xiàn)上面的邏輯,會(huì)發(fā)現(xiàn):
func foo5() {
values := []int{1, 2, 3, 5}
for _, val := range values {
go func() {
fmt.Printf("foo5 val = %v\n", val)
}()
}
}
foo5()
//foo3 val = 5
//foo3 val = 5
//foo3 val = 5
//foo3 val = 5其實(shí)這個(gè)問題的本質(zhì)同閉包的延遲綁定,或者說(shuō),這段匿名函數(shù)的對(duì)象就是閉包。在我們調(diào)用go func() { xxx }()的時(shí)候,只要沒有真正開始執(zhí)行這段代碼,那它還只是一段函數(shù)聲明。而在這段匿名函數(shù)被執(zhí)行的時(shí)候,才是內(nèi)部變量尋找真正賦值的時(shí)候。for-loop的遍歷幾乎是“瞬時(shí)”完成的,4個(gè)Go Routine真正被執(zhí)行在其后,所以會(huì)產(chǎn)生上面的情況。
到此這篇關(guān)于Golang 斷言與閉包使用解析的文章就介紹到這了,更多相關(guān)Go 斷言與閉包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
GOPROXY:解決go get golang.org/x包失敗問題
這篇文章主要介紹了GOPROXY:解決go get golang.org/x包失敗問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
使用goland調(diào)試遠(yuǎn)程代碼的操作步驟
大家都知道如何在goland調(diào)試遠(yuǎn)程代碼嗎?今天小編給大家分享一篇教程幫助大家學(xué)習(xí)goland調(diào)試遠(yuǎn)程代碼的操作步驟,感興趣的朋友跟隨小編一起看看吧2021-06-06
Golang 探索對(duì)Goroutine的控制方法(詳解)
下面小編就為大家分享一篇Golang 探索對(duì)Goroutine的控制方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Go語(yǔ)言實(shí)現(xiàn)自動(dòng)填寫古詩(shī)詞實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言實(shí)現(xiàn)自動(dòng)填寫古詩(shī)詞的相關(guān)資料,這是最近在項(xiàng)目中遇到的一個(gè)需求,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
Go語(yǔ)言中實(shí)現(xiàn)完美錯(cuò)誤處理實(shí)踐分享
Go?語(yǔ)言是一門非常流行的編程語(yǔ)言,由于其高效的并發(fā)編程和出色的網(wǎng)絡(luò)編程能力,越來(lái)越受到廣大開發(fā)者的青睞。本文我們就來(lái)深入探討一下Go?語(yǔ)言中的錯(cuò)誤處理機(jī)制吧2023-04-04
詳解如何為Go中的無(wú)限循環(huán)添加時(shí)間限制
在 Go 語(yǔ)言的開發(fā)過(guò)程中,我們有時(shí)需要在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行的任務(wù),例如監(jiān)聽或輪詢某些資源,這篇文章將通過(guò)一個(gè)實(shí)例詳細(xì)介紹如何為 Go 語(yǔ)言中的無(wú)限循環(huán)設(shè)置時(shí)間限制,保證程序的健壯性和可控性,需要的朋友可以參考下2024-04-04
gin正確多次讀取http?request?body內(nèi)容實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了gin正確多次讀取http?request?body內(nèi)容實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

