天天看點

Go語言探索 - 11(原創)

Go語言基礎系列部落格用到的所有示例代碼 上一篇文章

 主要學習了Go語言的切片以及Map。本篇文章主要學習的是Go語言中的接口、反射以及錯誤和異常處理。

接口:

回想一下,在Java中,有父類和子類的說法,父類主要是提供抽象的公共方法讓子類基于此拓展自身的功能。Java還有抽象類和接口

那麼,在Go語言中也提供了一種資料類型,接口。GO語言的接口是把所有的具有共性的方法定義在一起,其他類型隻要實作了接口内的方法就是實作了這個接口。(是不是很類似Java的接口?)

GO語言定義接口的文法格式:

type 接口名 interface {

    接口方法();

}

GO語言接口實戰:

為了看到效果,首先我們定義一個吃東西的接口,由于中西方飲食文化的差異,我們用筷子,歪果仁用刀叉,針對這種差異我們可以定義兩個結構體;我們讓這兩個結構體都實作吃的接口,由于接口不能直接new 但是可以new子類(也就是實作接口的結構體),是以可以有以下代碼:

Go語言探索 - 11(原創)

接口  - 1

好了,我們還可以繼續拓展:

Go語言探索 - 11(原創)

接口 - 2

結果如下:

Go語言探索 - 11(原創)

測試結果

拓展:空interface

空interface(interface{})不包含任何的method,正因為如此,所有的類型都實作了空interface。空interface對于描述起不到任何的作用(因為它不包含任何的method),但是空interface在我們需要存儲任意類型的數值的時候相當有用,因為它可以存儲任意類型的數值。它有點類似于C語言的void*類型。如下圖

Go語言探索 - 11(原創)

空接口

一個函數把interface{}作為參數,那麼他可以接受任意類型的值作為參數,如果一個函數傳回interface{},那麼也就可以傳回任意類型的值。任意類型的值這樣的好處是友善拓展

總之:interface就是一組抽象方法的集合,它必須由其他非interface類型實作,而不能自我實作。Go通過interface實作了duck-typing:即"當看到一隻鳥走起來像鴨子、遊泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子"。

反射:

Go語言實作了反射(最後看來跟Java的反射有異曲同工之效),所謂反射就是能檢查程式在運作時的狀态動态,拿到屬性值并可以指派的一種機制。GO語言使用反射功能會用到reflect包。

GO語言使用反射一般分為以下三步:

A:首先需要把需要反射的對象轉化成reflect對象(reflect.Type或者reflect.Value,根據不同的情況調用不同的函數)。這兩種擷取方式如下:

t := reflect.TypeOf(i)    //得到類型的中繼資料,通過t我們能擷取類型定義裡面的所有元素

v := reflect.ValueOf(i)  //得到實際的值,通過v我們擷取存儲在裡面的值,還可以去改變值

B:轉為reflect對象後,我們可以将reflect對象轉化成相應的值,例如

tag := t.Elem().Field(0).Tag  //擷取定義在struct裡面的标簽字段

name := v.Elem().Field(0).String()  //擷取存儲在第一個字段裡面的值

C:反射的字段必須是可修改的(也就是Java中反射的API,允許反射)

下面是一個簡單的反射例子,通過擷取x的值,然後反射調用,在修改值的操作:

Go語言探索 - 11(原創)

反 射

錯誤和異常處理:

錯誤指的是可能出現問題的地方出現了問題,比如打開一個檔案時失敗,這種情況在人們的意料之中 

異常指的是不應該出現問題的地方出現了問題,比如引用了空指針、數組越界、除數為0等等

是以:

Go引入error接口作為錯誤處理的标準模式,如果函數要傳回錯誤,那麼傳回值類型中要包含error;

Go引入兩個内置函數panic和recover來觸發和終止異常處理流程,同時引入關鍵字defer來延遲執行defer後面的函數。

基于錯誤和異常的處理這裡推薦一篇非常不錯的部落格:

Golang錯誤和異常處理的正确姿勢

本篇文章關于Go語言中的接口、反射以及錯誤和異常處理的内容基本上就結束了。

如果這篇文章對你有幫助,希望各位看官留下寶貴的star,謝謝。

Ps:著作權歸作者所有,轉載請注明作者, 商業轉載請聯系作者獲得授權,非商業轉載請注明出處(開頭或結尾請添加轉載出處,添加原文url位址),文章請勿濫用,也希望大家尊重筆者的勞動成果