介面在go語言有著至關重要的地位。介面是go語言這個型別系統的基石,讓go語言在基礎程式設計哲學的探索上達到了前所未有的高度。
介面解除了型別依賴,有助於減少使用者的可視方法,遮蔽了內部結構和實現細節。但是介面實現機制會有執行期開銷,也不能濫用介面。相對於包,或者不會頻繁變化的內部模組之間,不需要抽象出介面來強行分離。介面最常用的使用場景,是對包提供訪問,或預留擴充套件空間。
介面內部的實現:
type iface struce
介面結構是包含兩個欄位的資料結構,第乙個包含乙個指向內部表的指標,這個內部表叫做itable,包含子所儲存的值的型別資訊。itable包含了已儲存的值的型別資訊已經值關聯的一組方法。第二個字段指向儲存值的指標,指向賦值的這個物件。
從內部實現來看,介面本身也是一種結構型別,只是編譯器會對其做很多的限制。
介面用來定義行為的型別,這些被定義的行為不由介面直接實現,而是通過方法由使用者定義的型別實現。如果使用者定義的型別實現了某個介面宣告的一組方法,那麼這個使用者定義的型別物件可以直接賦值給介面型別物件。這個賦值會把使用者定義的型別值存入介面型別的值。
對介面值方法的呼叫會執行介面值裡儲存的使用者定義的型別值對應的方法。任何使用者定義的型別都可以實現任何介面。如果離開了使用者定義型別的實現,介面並沒有具體的行為,使用者定義的型別通常稱為實體型別。
介面通常以er作為名稱字尾,方法名是宣告組成部分,但引數名可不同或省略。
方法集定義了介面的實現規則。
type tester inte***ce
type
data struce{}
func (*data)test{}
func (data) string() string
func main()
為什麼var t tester=d編譯時會產生錯誤,由於定義的方法集中,test方法是指標接收者,而string方法是值接收者,定義方法集是我們需要了解定義了一組關聯到給定型別的值或者指標的方法。定義方法時使用的接收者的型別決定了這個方法時關聯到值,還是指標,或者兩個都關聯。
如果使用指標接受者來實現乙個介面,那麼只有指向型別的指標才能實現對應的介面。如果使用值接收者來實現乙個介面,那麼這個型別的值和指標都能夠實現對應的介面。
如果介面沒有任何方法宣告,那麼這個介面就是乙個空介面(inte***ce{}),它的用途類似物件導向裡面的object,可被賦值為任何型別的物件。
介面變數預設值為nil,如果實現介面的型別支援,可以做相等運算。
func main()
fmt.println(t1==nil,t1==t2)
t1,t2=100
,100
fmt.println(t1==t2)
t1,t2=map[string]int{},map[string]int{}
fmt.println(t1==t2)
}//輸出:
true
true
true
panic:tuntime err:...
可以像匿名函式一樣,嵌入其他介面,目標型別方法集中必須擁有包含嵌入介面方法在內的全部方法才能實現該介面。
嵌入其他介面型別,相當於將其宣告的方法匯入,這就要求不能有同名的方法,因為不支援過載,不能嵌入自身型別,會導致遞迴錯誤。
超集介面變數可隱式轉換成子集,反過來不行。
支援匿名介面型別,可直接定義變數,或作為結構字段型別。
type
data struct{}
func (data)string() string
type node struct
}func main()=data
{} n:=node
fmt.println(data.string())
}
我們無法修改介面儲存的複製品:
func main()
var t inte***ce{} = d
p:=&t.(data) //錯誤,不能取t.(data)的位址
t.(data).x = 200 //錯誤,不能賦值
}
可以修改為:
func main()
var t inte***ce{} = &d
t.(*data).x = 200 //錯誤,不能取t.(data)的位址
}
我們可將介面變數還原為原始型別,或用來判斷是否實現了某個更具體的介面型別。
type
data int
func (d data) string() string
func main()=d
if n,ok:=x.(string);ok
if n1,ok:=x.(data);ok
}
使用ok這種判斷模式,即便轉換失敗也不會引發panic,還可以使用在switch語句在多種型別間做出判斷,這樣空介面可以有更大的使用空間。
在專案前期設計合理的介面並不容易,而在**重構,模組拆分時再分離出介面,用來解耦很常見。
Go 語言介面
go 語言提供了另外一種資料型別即介面,它把所有的具有共性的方法定義在一起,任何其他型別只要實現了這些方法就是實現了這個介面。例項 定義介面 type inte ce name inte ce 定義結構體 type struct name struct 實現介面方法 func struct name...
Go語言 介面
介面代表一種呼叫契約,是多個方法宣告的集合。介面要實現的是做什麼,而不關心如何做。介面最常見的使用場景是對包外提供訪問,或預留擴充套件空間。go語言介面實現機制很簡潔,只要目標型別方法集內包含介面宣告的全部方法,就被視為實現了該介面,無需做顯示宣告,當然目標型別可實現多個介面。其實介面也是一中結構,...
Go語言 介面
在go語言中,乙個介面型別總是代表著某一種型別 即所有實現它的型別 的行為。乙個介面型別的宣告通常會包含關鍵字type 型別名稱 關鍵字inte ce以及由花括號包裹的若干方法宣告。示例如下 type animal inte ce注意,介面型別中的方法宣告是普通的方法宣告的簡化形式。它們只包括方法名...