<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
空介面是特殊形式的介面型別,普通的介面都有方法,而空介面沒有定義任何方法口,也因此,我們可以說所有型別都至少實現了空介面。
type test interface { }
每一個介面都包含兩個屬性,一個是值,一個是型別。
var i interface{} fmt.Printf("型別:%T----值:%vn", i, i) //型別:<nil>----值:<nil>
可見對於空介面來說,這兩者都是 nil
第一,通常我們會直接使用 interface{}
作為型別宣告一個範例,而這個範例可以承載任意型別的值。
func main() { var i interface{} i = 100 fmt.Println(i) //100 i = "yif" fmt.Println(i) //yif i = 3.14 fmt.Println(i) //3.14 i = false fmt.Println(i) //false }
第二,如果想讓你的函數可以接收任意型別的值 ,也可以使用空介面。如下程式碼都正常列印:
func main() { i := 100 s := "yif" f := 3.14 test(i) test(s) test(f) } func test(i interface{}) { fmt.Println(i) }
上面寫法有點麻煩,可以使用可變引數的函數。如下:
func main() { i := 100 s := "yif" f := 3.14 test(i, s, f) } func test(res ...interface{}) { fmt.Println(res) //res是切片 for k, v := range res { fmt.Println(k, v) } }
結果:
D:workspacegosrctest>go run main.go
[100 yif 3.14]
0 100
1 yif
2 3.14
第三,你也定義一個可以接收任意型別的 array、slice、map、strcut,例如這邊定義一個切片
func main() { sli := make([]interface{}, 4) sli[0] = 100 sli[1] = "yif" sli[2] = []int{1, 2, 3} sli[3] = [...]int{5, 6, 7} fmt.Println(sli) for k, v := range sli { fmt.Println(k, v) } }
結果:
D:workspacegosrctest>go run main.go
[100 yif [1 2 3] [5 6 7]]
0 100
1 yif
2 [1 2 3]
3 [5 6 7]
**第一,**空介面可以承載任意值,但不代表任意型別就可以承接空介面型別的值
空介面型別可以儲存任何值,也可以從空介面中取出原值。
但要是你把一個空介面型別的物件,再賦值給一個固定型別(比如 int, string等型別)的物件賦值,是會報錯的。
var i interface{} = 100 var t int = i // cannot use i (type interface {}) as type int in assignment: need type assertion
但是你使用短變數宣告,是可以的:
var i interface{} = 100 t := i fmt.Println(t) //100
因為編譯器會根據等號右邊的值來推導變數的型別完成初始化。
**第二:**當空介面承載陣列和切片後,該物件無法再進行切片
sli := []int{1, 2, 3, 4} var i interface{} i = sli fmt.Println(i[1:2]) //cannot slice i (type interface {})
型別斷言(Type Assertion)是一個使用在介面值上的操作,用於檢查介面型別變數所持有的值是否實現了期望的介面或者具體的型別
型別斷言,僅能對靜態型別為空介面(interface{})的物件進行斷言,否則會丟擲錯誤
在Go語言中型別斷言的第一種語法格式如下:
t := i.(T)
這個表示式可以斷言一個介面物件(i)裡不是 nil,並且介面物件(i)儲存的值的型別是 T,如果斷言成功,就會返回值給 t,如果斷言失敗,就會觸發 panic。
func main() { var i interface{} = 100 t := i.(int) fmt.Println(t) //100 fmt.Println("------------------------------------") s := i.(string) fmt.Println(s) }
結果【執行第二次斷言的時候失敗了,並且觸發了 panic】:
D:workspacegosrctest>go run main.go
100
------------------------------------
panic: interface conversion: interface {} is int, not stringgoroutine 1 [running]:
main.main()
D:/workspace/go/src/test/main.go:32 +0x10e
exit status 2
如果要斷言的介面值是 nil,那我們來看看也是不是也如預期一樣會觸發panic
var i interface{} var _ = i.(interface{})
結果:
D:workspacegosrctest>go run main.go
panic: interface conversion: interface is nil, not interface {}goroutine 1 [running]:
main.main()
D:/workspace/go/src/test/main.go:27 +0x34
exit status 2
在Go語言中型別斷言的另一種語法格式如下:
t, ok:= i.(T)
和上面一樣,這個表示式也是可以斷言一個介面物件(i)裡不是 nil,並且介面物件(i)儲存的值的型別是 T,如果斷言成功,就會返回其型別給 t,並且此時 ok 的值 為 true,表示斷言成功。
如果介面值的型別,並不是我們所斷言的 T,就會斷言失敗,但和第一種表示式不同的事,這個不會觸發 panic,而是將 ok 的值設為 false ,表示斷言失敗,此時t 為 T 的零值。
func main() { var i interface{} = 10 t1, ok := i.(int) fmt.Printf("%d-%tn", t1, ok) fmt.Println("=====分隔線1=====") t2, ok := i.(string) fmt.Printf("%s-%tn", t2, ok) fmt.Println("=====分隔線2=====") var k interface{} // nil t3, ok := k.(interface{}) fmt.Println(t3, "-", ok) fmt.Println("=====分隔線3=====") k = 10 t4, ok := k.(interface{}) fmt.Printf("%d-%tn", t4, ok) t5, ok := k.(int) fmt.Printf("%d-%tn", t5, ok) }
結果【執行後輸出如下,可以發現在執行第二次斷言的時候,雖然失敗了,但並沒有觸發了 panic】:
D:workspacegosrctest>go run main.go
10-true
=====分隔線1=====
-false
=====分隔線2=====
<nil> - false
=====分隔線3=====
10-true
10-true
上面這段輸出,你要注意的是第二個斷言的輸出在-false
之前並不是有沒有輸出任何 t2 的值,而是由於斷言失敗,所以 t2 得到的是 string 的零值也是 ""
,它是零長度的,所以你看不到其輸出。
如果需要區分多種型別,可以使用 type switch 斷言。
func main() { test(100) test("yif") test(3.14) var i interface{} //nil test(i) test(nil) } func test(i interface{}) { switch r := i.(type) { case int: fmt.Println(r, "是int型") case string: fmt.Println(r, "是字串") case nil: fmt.Println(r, "是nil") default: fmt.Println("沒有結果!") } }
結果:
D:workspacegosrctest>go run main.go
100 是int型
yif 是字串
沒有結果!
<nil> 是nil
<nil> 是nil
到此這篇關於Golang空介面與型別斷言的實現的文章就介紹到這了,更多相關Golang空介面與型別斷言內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45