上一篇文章 主要學習了Go語言的切片以及Map。本篇文章主要學習的是Go語言中的介面、反射以及錯誤和異常處理。
介面:
回想一下,在Java中,有父類和子類的說法,父類主要是提供抽象的公用方法讓子類基於此拓展自身的功能。Java還有抽象類別和介面
那麼,在Go語言中也提供了一種資料類型,介面。GO語言的介面是把所有的具有共性的方法定義在一起,其他類型只要實現了介面內的方法就是實現了這個介面。(是不是很類似Java的介面?)
GO語言定義介面的文法格式:
type 介面名 interface {
介面方法();
}
GO語言介面實戰:
為了看到效果,首先我們定義一個吃東西的介面,由於中西方飲食文化的差異,我們用筷子,歪果仁用刀叉,針對這種差異我們可以定義兩個結構體;我們讓這兩個結構體都實現吃的介面,由於介面不能直接new 但是可以new子類(也就是實現介面的結構體),因此可以有以下代碼:
介面 - 1
好了,我們還可以繼續拓展:
介面 - 2
結果如下:
測試結果
拓展:空interface
空interface(interface{})不包含任何的method,正因為如此,所有的類型都實現了空interface。空interface對於描述起不到任何的作用(因為它不包含任何的method),但是空interface在我們需要儲存任意類型的數值的時候相當有用,因為它可以儲存任意類型的數值。它有點類似於C語言的void*類型。如
空介面
一個函數把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的值,然後反射調用,在修改值的操作:
反 射
錯誤和異常處理:
錯誤指的是可能出現問題的地方出現了問題,比如開啟一個檔案時失敗,這種情況在人們的意料之中
異常指的是不應該出現問題的地方出現了問題,比如引用了null 指標、數組越界、除數為0等等
因此:
Go引入error介面作為錯誤處理的標準模式,如果函數要返回錯誤,那麼傳回值類型中要包含error;
Go引入兩個內建函數panic和recover來觸發和終止異常處理流程,同時引入關鍵字defer來順延強制defer後面的函數。
基於錯誤和異常的處理這裡推薦一篇非常不錯的部落格:
Golang錯誤和異常處理的正確姿勢
本篇文章關於Go語言中的介面、反射以及錯誤和異常處理的內容基本上就結束了。
如果這篇文章對你有協助,希望各位看官留下寶貴的star,謝謝。
Ps:著作權歸作者所有,轉載請註明作者, 商業轉載請聯絡作者獲得授權,非商業轉載請註明出處(開頭或結尾請添加轉載出處,添加原文url地址),文章請勿濫用,也希望大家尊重筆者的勞動成果