Go 語言中的空接口(推薦)
在自己學(xué)習(xí) Golang 的這段時間里,我寫了詳細的學(xué)習(xí)筆記放在我的個人微信公眾號 《Go編程時光》,對于 Go 語言,我也算是個初學(xué)者,因此寫的東西應(yīng)該會比較適合剛接觸的同學(xué),如果你也是剛學(xué)習(xí) Go 語言,不防關(guān)注一下,一起學(xué)習(xí),一起成長。
我的在線博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
1. 什么是空接口?
空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒有定義任何方法口,也因此,我們可以說所有類型都至少實現(xiàn)了空接口。
type empty_iface interface { }
每一個接口都包含兩個屬性,一個是值,一個是類型。
而對于空接口來說,這兩者都是 nil,可以使用 fmt 來驗證一下
package main import ( "fmt" ) func main() { var i interface{} fmt.Printf("type: %T, value: %v", i, i) }
輸出如下
type: <nil>, value: <nil>
2. 如何使用空接口?
第一,通常我們會直接使用 interface{}
作為類型聲明一個實例,而這個實例可以承載任意類型的值。
package main import ( "fmt" ) func main() { // 聲明一個空接口實例 var i interface{} // 存 int 沒有問題 i = 1 fmt.Println(i) // 存字符串也沒有問題 i = "hello" fmt.Println(i) // 存布爾值也沒有問題 i = false fmt.Println(i) }
第二,如果想讓你的函數(shù)可以接收任意類型的值 ,也可以使用空接口
接收一個任意類型的值 示例
package main import ( "fmt" ) func myfunc(iface interface{}){ fmt.Println(iface) } func main() { a := 10 b := "hello" c := true myfunc(a) myfunc(b) myfunc(c) }
接收任意個任意類型的值 示例
package main import ( "fmt" ) func myfunc(ifaces ...interface{}){ for _,iface := range ifaces{ fmt.Println(iface) } } func main() { a := 10 b := "hello" c := true myfunc(a, b, c) }
第三,你也定義一個可以接收任意類型的 array、slice、map、strcut,例如這邊定義一個切片
package main import "fmt" func main() { any := make([]interface{}, 5) any[0] = 11 any[1] = "hello world" any[2] = []int{11, 22, 33, 44} for _, value := range any { fmt.Println(value) } }
3. 空接口幾個要注意的坑
坑1:空接口可以承載任意值,但不代表任意類型就可以承接空接口類型的值
從實現(xiàn)的角度看,任何類型的值都滿足空接口。因此空接口類型可以保存任何值,也可以從空接口中取出原值。
但要是你把一個空接口類型的對象,再賦值給一個固定類型(比如 int, string等類型)的對象賦值,是會報錯的。
package main func main() { // 聲明a變量, 類型int, 初始值為1 var a int = 1 // 聲明i變量, 類型為interface{}, 初始值為a, 此時i的值變?yōu)? var i interface{} = a // 聲明b變量, 嘗試賦值i var b int = i }
這個報錯,它就好比可以放進行禮箱的東西,肯定能放到集裝箱里,但是反過來,能放到集裝箱的東西就不一定能放到行禮箱了,在 Go 里就直接禁止了這種反向操作。(聲明:底層原理肯定還另有其因,但對于新手來說,這樣解釋也許會容易理解一些。)
.\main.go:11:6: cannot use i (type interface {}) as type int in assignment: need type assertion
坑2::當(dāng)空接口承載數(shù)組和切片后,該對象無法再進行切片
package main import "fmt" func main() { sli := []int{2, 3, 5, 7, 11, 13} var i interface{} i = sli g := i[1:3] fmt.Println(g) }
執(zhí)行會報錯。
.\main.go:11:8: cannot slice i (type interface {})
坑3:當(dāng)你使用空接口來接收任意類型的參數(shù)時,它的靜態(tài)類型是 interface{},但動態(tài)類型(是 int,string 還是其他類型)我們并不知道,因此需要使用類型斷言。
package main import ( "fmt" ) func myfunc(i interface{}) { switch i.(type) { case int: fmt.Println("參數(shù)的類型是 int") case string: fmt.Println("參數(shù)的類型是 string") } } func main() { a := 10 b := "hello" myfunc(a) myfunc(b) }
輸出如下
參數(shù)的類型是 int
參數(shù)的類型是 string
總結(jié)
到此這篇關(guān)于Go 語言中的空接口的文章就介紹到這了,更多相關(guān)go 語言空接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go?函數(shù)中獲取調(diào)用者的函數(shù)名和文件名及行號
這篇文章主要介紹了Go?函數(shù)中獲取調(diào)用者的函數(shù)名和文件名及行號,文章圍主題詳細內(nèi)容展開相關(guān)介紹,感興趣的小伙伴可以參考一下2022-05-05淺談Go語言多態(tài)的實現(xiàn)與interface使用
如果大家系統(tǒng)的學(xué)過C++、Java等語言以及面向?qū)ο蟮脑挘嘈艖?yīng)該對多態(tài)不會陌生。多態(tài)是面向?qū)ο蠓懂牣?dāng)中經(jīng)常使用并且非常好用的一個功能,它主要是用在強類型語言當(dāng)中,像是Python這樣的弱類型語言,變量的類型可以隨意變化,也沒有任何限制,其實區(qū)別不是很大2021-06-06Go語言數(shù)據(jù)結(jié)構(gòu)之二叉樹可視化詳解
這篇文章主要為大家詳細介紹了Go語言數(shù)據(jù)結(jié)構(gòu)中二叉樹可視化的方法詳解,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-09-09Golang內(nèi)存泄露場景與定位方式的實現(xiàn)
Golang有自動垃圾回收機制,但是仍然可能會出現(xiàn)內(nèi)存泄漏的情況,本文主要介紹了Golang內(nèi)存泄露場景與定位方式的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-04-04一文帶你了解Go語言實現(xiàn)的并發(fā)神庫conc
前幾天逛github發(fā)現(xiàn)了一個有趣的并發(fā)庫-conc,這篇文章將為大家詳細介紹一下這個庫的實現(xiàn),文中的示例代碼講解詳細,感興趣的可以了解一下2023-01-01