91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang中interface{}的注意事項是什么

發布時間:2023-03-09 14:23:29 來源:億速云 閱讀:69 作者:iii 欄目:開發技術

這篇“Golang中interface{}的注意事項是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Golang中interface{}的注意事項是什么”文章吧。

interface {} 可以用于模擬多態

xdm 咱們寫一個簡單的例子,就舉動物的例子

寫一個 Animal 的接口,類似于 java 里面的抽象類 ,Animal 的接口 中有 2 個方案待實現

寫一個 Cat 來繼承 Animal , 實現 Eat 方法和 Drink 方法

  • 動物都有吃和喝的行為,小貓吃的行為是吃魚,小貓的喝的行為是喝可樂

  • 最后在主函數中,使用父類的指針,來指向子類的實例化的一個子類地址

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"))
}

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

這里需要注意,Animal 本身是 接口類型,自身就是一個指針

運行上述代碼查看效果

# go run main.go
i like
abandon

沒有毛病,小貓瞇愛吃魚,不愛喝水

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

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

咱們還是用上面的例子, 添加一個 testInterface 函數,來實踐一下

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")
    }
}

可以猜猜看,上面這個小案例會輸出什么結果

理論上來看,testInterface 函數中我們只是創建了一個 Cat 指針,并沒有賦值,因此默認是一個零值,因此會是一個 nil,那么 return 的時候,應該也是 return nil 才對吧,因此按照代碼的邏輯來說應該是輸出 test is nil

執行上述代碼后,查看結果

# go run main.go
test is not nil

看到上面的結果,是不是覺得很奇怪,和自己的預期不一致

沒關系,之前的文章我們說到過,覺得一個技術點奇怪,不是我們所期望的效果,原因是我們對其原理不夠了解,不夠熟悉

現在先來回答一下上面的問題

空接口:意思是沒有方法的接口,interface{} 源碼中表示為 eface 結構體

非空接口:表示有包含方法的接口 , interface{} 源碼中表示為 iface 結構體

暫時先來直接介紹源碼中的結構體

iface結構體,非空

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

指的是具體的類型信息,是一個 itab 結構,結構中成員如上,這里面包含的都是借口的關鍵信息,例如 hash 值 ,函數指針,等等,后續詳細剖析 interface{} 原理的時候再統一說

data

具體的數據信息

eface結構體

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

_type

類型信息,和上面的 非空接口類似 , 這個_type 類型決定下面的 data 字段如何去解釋數據

data

具體的數據信息

看到這里,細心的 xdm 是不是就可以看出來,我們上面寫的 Animal 接口,其實是一個非空接口,因為里面有包含方法,所以他的底層是一個 iface 結構體 ,非空接口

那么初始化的一個空指針 c ,實際上是 iface 結構體里面的 data 字段為空而已,數據為空而已,但是 iface 這個結構體自己不是空的,所以上述代碼走的邏輯是 test is not nil

Golang中interface{}的注意事項是什么

這里順帶說一下,golang 中,還有哪些數據結構是和 nil 比較是否為零值,這個點我們也可以看看源碼

// 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

源碼中有說到,可以對 指針,通道,函數,接口,map,切片類型使用 nil

以上就是關于“Golang中interface{}的注意事項是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

炉霍县| 城市| 塔城市| 开平市| 阿克苏市| 阜宁县| 陆丰市| 阆中市| 吴忠市| 修文县| 鹰潭市| 庆阳市| 竹溪县| 卓资县| 东乡族自治县| 黄冈市| 巴彦淖尔市| 金门县| 西畴县| 霍林郭勒市| 抚远县| 新野县| 重庆市| 开原市| 浦城县| 建湖县| 临海市| 上饶市| 望奎县| 峡江县| 松阳县| 双江| 石河子市| 江北区| 新津县| 邹平县| 太原市| 东方市| 亳州市| 余庆县| 广丰县|