最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

關(guān)于 interface{} 會(huì)有啥注意事項(xiàng)?上

2023-03-06 21:50 作者:阿兵云原生  | 我要投稿

學(xué)習(xí) golang ,對(duì)于 interface{} 接口類(lèi)型,我們一定繞不過(guò),咱們一起來(lái)看看 使用 ?interface{} 的時(shí)候,都有哪些注意事項(xiàng)吧

interface {} 可以用于模擬多態(tài)

xdm 咱們寫(xiě)一個(gè)簡(jiǎn)單的例子,就舉動(dòng)物的例子

寫(xiě)一個(gè) Animal 的接口,類(lèi)似于 java 里面的抽象類(lèi) ,Animal 的接口 中有 2 個(gè)方案待實(shí)現(xiàn)

寫(xiě)一個(gè) Cat 來(lái)繼承 Animal , 實(shí)現(xiàn) Eat 方法和 Drink 方法

  • 動(dòng)物都有吃和喝的行為,小貓吃的行為是吃魚(yú),小貓的喝的行為是喝可樂(lè)

  • 最后在主函數(shù)中,使用父類(lèi)的指針,來(lái)指向子類(lèi)的實(shí)例化的一個(gè)子類(lèi)地址

type?Animal?interface?{
?Eat(string)?string
?Drink(string)?string
}

type?Cat?struct{}

func?(c?*Cat)?Eat(food?string)?string?{
?if?food?!=?"fish"?{
??return?"i?dislike"
?}?else?{
??return?"i?like"
?}

}
func?(c?*Cat)?Drink(drink?string)?string?{
?if?drink?==?"coke"?{
??return?"i?love"
?}else{
??return?"abandon"
?}
}
func?main(){
?var?a?Animal?=?&Cat{}
?fmt.Println(a.Eat("fish"))
?fmt.Println(a.Drink("water"))
}

看到上述代碼,會(huì)不會(huì)有這樣的疑問(wèn),命名是 &Cat{} 是取地址的,為什么 var a Animal 不寫(xiě)成指針呢?

這里需要注意,Animal 本身是 接口類(lèi)型,自身就是一個(gè)指針

運(yùn)行上述代碼查看效果

#?go?run?main.go
i?like
abandon

沒(méi)有毛病,小貓瞇愛(ài)吃魚(yú),不愛(ài)喝水

interface{} 需要注意空和非空的情況

什么叫做空的 interface{} , ?什么又叫做非空的 interface{} 呢?

咱們還是用上面的例子, 添加一個(gè) testInterface 函數(shù),來(lái)實(shí)踐一下

func?testInterface()?Animal?{
?var?c?*Cat
?return?c
}

func?main()?{
?test?:=?testInterface()
?if?test?==?nil?{
??fmt.Println("test?is?nil")
?}?else?{
??fmt.Println("test?is?not?nil")
?}
}

可以猜猜看,上面這個(gè)小案例會(huì)輸出什么結(jié)果

  • 理論上來(lái)看,testInterface 函數(shù)中我們只是創(chuàng)建了一個(gè) Cat 指針,并沒(méi)有賦值,因此默認(rèn)是一個(gè)零值,因此會(huì)是一個(gè) nil,那么 return 的時(shí)候,應(yīng)該也是 return nil 才對(duì)吧,因此按照代碼的邏輯來(lái)說(shuō)應(yīng)該是輸出 ?test is nil

執(zhí)行上述代碼后,查看結(jié)果

#?go?run?main.go
test?is?not?nil

看到上面的結(jié)果,是不是覺(jué)得很奇怪,和自己的預(yù)期不一致

沒(méi)關(guān)系,之前的文章我們說(shuō)到過(guò),覺(jué)得一個(gè)技術(shù)點(diǎn)奇怪,不是我們所期望的效果,原因是我們對(duì)其原理不夠了解,不夠熟悉

現(xiàn)在先來(lái)回答一下上面的問(wèn)題

空接口:意思是沒(méi)有方法的接口,interface{} 源碼中表示為 ? eface 結(jié)構(gòu)體

非空接口:表示有包含方法的接口 , interface{} 源碼中表示為 ? iface 結(jié)構(gòu)體

暫時(shí)先來(lái)直接介紹源碼中的結(jié)構(gòu)體

iface 結(jié)構(gòu)體 , 非空

type?iface?struct?{
?tab??*itab
?data?unsafe.Pointer
}

type?itab?struct?{
?inter??*interfacetype
?_type??*_type
?link???*itab
?hash???uint32?//?copy?of?_type.hash.?Used?for?type?switches.
?bad????bool???//?type?does?not?implement?interface
?inhash?bool???//?has?this?itab?been?added?to?hash?
?unused?[2]byte
?fun????[1]uintptr?//?variable?sized
}

  • tab

    指的是具體的類(lèi)型信息,是一個(gè) ?itab 結(jié)構(gòu),結(jié)構(gòu)中成員如上,這里面包含的都是借口的關(guān)鍵信息,例如 hash 值 ,函數(shù)指針,等等,后續(xù)詳細(xì)剖析 interface{} 原理的時(shí)候再統(tǒng)一說(shuō)

  • data

具體的數(shù)據(jù)信息

eface 結(jié)構(gòu)體

type?eface?struct?{
????_type?*_type
????data??unsafe.Pointer
}
type?_type?struct?{
????size???????uintptr??//?表示的是?類(lèi)型的大小
????ptrdata????uintptr??//?值的是前綴指針的內(nèi)存大小
????hash???????uint32???//?計(jì)算數(shù)據(jù)的?hash?值
????tflag??????tflag
????align??????uint8????//??進(jìn)行內(nèi)存對(duì)齊的
????fieldalign?uint8?
????kind???????uint8?
????alg????????*typeAlg?
????gcdata????*byte
????str???????nameOff
????ptrToThis?typeOff
}

  • _type

類(lèi)型信息,和上面的 非空接口類(lèi)似 , 這個(gè)_type 類(lèi)型決定下面的 data 字段如何去解釋數(shù)據(jù)

  • data

具體的數(shù)據(jù)信息

看到這里,細(xì)心的 xdm 是不是就可以看出來(lái),我們上面寫(xiě)的 Animal 接口,其實(shí)是一個(gè)非空接口,因?yàn)槔锩嬗邪椒ǎ?strong>所以他的底層是一個(gè) iface 結(jié)構(gòu)體 ?,非空接口

那么初始化的一個(gè)空指針 c ,實(shí)際上是 iface 結(jié)構(gòu)體里面的 data 字段為空而已,數(shù)據(jù)為空而已,但是 iface 這個(gè)結(jié)構(gòu)體自己不是空的,所以上述代碼走的邏輯是 ?test is not nil

這里順帶說(shuō)一下,golang 中,還有哪些數(shù)據(jù)結(jié)構(gòu)是和 nil 比較是否為零值,這個(gè)點(diǎn)我們也可以看看源碼

//?nil?is?a?predeclared?identifier?representing?the?zero?value?for?a
//?pointer,?channel,?func,?interface,?map,?or?slice?type.
var?nil?Type?//?Type?must?be?a?pointer,?channel,?func,?interface,?map,?or?slice?type

源碼中有說(shuō)到,可以對(duì) 指針,通道,函數(shù),接口,map,切片類(lèi)型使用 ?nil

好了,本次就到這里,知識(shí)點(diǎn)要用起來(lái)才有價(jià)值

歡迎點(diǎn)贊,關(guān)注,收藏

朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力

好了,本次就到這里

技術(shù)是開(kāi)放的,我們的心態(tài),更應(yīng)是開(kāi)放的。擁抱變化,向陽(yáng)而生,努力向前行。

我是阿兵云原生,歡迎點(diǎn)贊關(guān)注收藏,下次見(jiàn)~


關(guān)于 interface{} 會(huì)有啥注意事項(xiàng)?上的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
信阳市| 泸定县| 瑞金市| 同心县| 澳门| 镶黄旗| 武汉市| 全南县| 梁河县| 平江县| 进贤县| 正定县| 开阳县| 滁州市| 清河县| 重庆市| 丹阳市| 山丹县| 平顶山市| 曲麻莱县| 武汉市| 双桥区| 曲沃县| 沅江市| 石阡县| 安达市| 织金县| 安宁市| 怀安县| 沂南县| 朔州市| 穆棱市| 延边| 云霄县| 荥经县| 航空| 夏津县| 临武县| 文成县| 鄱阳县| 曲麻莱县|