您好,登錄后才能下訂單哦!
本篇內容主要講解“Go語言接口賦值實例介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Go語言接口賦值實例介紹”吧!
先看看將指定類型的對象實例賦值給接口,這要求該對象對應的類實現了接口要求的所有方法,這個是自然,否則也就不能算作實現該接口了,例如之前我們定義過一個Integer類型
type Integer int func (a Integer) Equal(i Integer) bool { return a == i} func (a Integer) LessThan(i Integer) bool { return a < i} func (a Integer) MoreThan(i Integer) bool { return a > i} func (a *Integer) Increase(i Integer) { *a = *a + i} func (a *Integer) Decrease(i Integer) { *a = *a - i}
相應地,我們定義一個接口IntNumber:
type IntNumber interface { Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool Increase(i Integer) Decrease(i Integer)}
安裝 Go 語言的約定,Integer類型實現了IntNumber接口。然后我們可以這樣將Integer類型對應的對象實例賦值給IntNumber接口:
var a Integer = 1var b IntNumber = &a
注意到上述賦值語句中,我們將對象實例a的指針應用賦值給了接口變量,為什么要這么做呢?因為 Go 語言會根據類似下面這樣的非指針成員方法:
func (a Integer) Equal(i Integer) bool
自動生成一個新的與之對應的指針成員方法:
func (a *Integer) Equal(i Integer) bool { return (*a).Equal(i)}
這樣一來,類型*Integer就存在所有IntNumber接口中聲明的方法,而Integer類型不包含指針方法Increase和Decrease(關于這一點我們前面已經介紹過),所以嚴格來說,只有*Integer類型實現了IntNumber接口。如果我們貿然將a的值引用賦值給b,編譯時會報錯:
cannot use a (type Integer) as type IntNumber in assignment: Integer does not implement IntNumber (Decrease method has pointer receiver)
顯然,如果Integer類中實現的方法不是指針方法,則進行接口賦值時,傳遞對象實例的值引用給接口變量即可,否則需要傳遞指針變量。為了驗證這一點,我們可以再創建一個新的接口IntNumber2:
type IntNumber2 interface { Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool}
然后將對象實例a的值引用賦值給IntNumber接口變量:
var a Integer = 1varb1IntNumber=&avar b2 IntNumber2 = a
則上面兩條接口賦值語句都可以編譯通過。
接下來我們來看將一個接口賦值給另一個接口:在 Go 語言中,只要兩個接口擁有相同的方法列表(與順序無關),那么它們就是等同的,可以相互賦值。
下面我們來編寫對應的示例代碼,這是第一個接口Number1,位于oop1包中:
package oop1 type Number1 interface { Equal(i int) bool LessThan(i int) bool MoreThan(i int) bool}
這是第二個接口Number2,位于oop2包中:
package oop2 type Number2 interface { Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool}
這里我們定義了兩個接口,一個叫oop1.Number1,一個叫oop2.Number2,兩者都定義五個相同的方法,只是順序不同而已。在 Go 語言中,這兩個接口實際上并無區別,因為:
任何實現了oop1.Number1接口的類,也實現了oop2.Number2;任何實現了oop1.Number1接口的對象實例都可以賦值給oop2.Number2,反之亦然;在任何地方使用oop1.Number1接口與使用oop2.Number2并無差異。
接下來我們定義一個實現了這兩個接口的類Number:
type Number int; func (n Number) Equal(i int) bool { return int(n) == i;} func (n Number) LessThan(i int) bool { return int(n) < i;} func (n Number) MoreThan(i int) bool { return int(n) > i;}
所以下面這些賦值代碼都是合法的,會編譯通過:
var num1 Number = 1;var num2 oop1.Number1 = num1var num3 oop2.Number2 = num2
此外,接口賦值并不要求兩個接口完全等價(方法完全相同)。如果接口 A 的方法列表是接口 B 的方法列表的子集,那么接口 B 可以賦值給接口 A。例如,假設Number2接口定義如下:
type Number2 interface { Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool Add(i int)}
要讓Number類繼續保持實現這兩個接口,需要在Number類定義中新增一個Add方法實現:
func (n *Number) Add(i int) { *n = *n + Number(i);}
接下來,將上面的接口賦值語句改寫如下即可:
var num1 oop1.Number = 1;var num2 oop2.Number2 = &num1;var num3 oop1.Number1 = num2;
但是反過來不行:
var num1 oop1.Number = 1;var num2 oop1.Number1 = &num1;var num3 oop2.Number2 = num2; // 這一段編譯出錯
因為Number1接口中沒有Add方法,這一點和 PHP/Java 中子類實例可以直接賦值給父類,而父類實例不能直接賦值給子類頗有些異曲同工。
到此,相信大家對“Go語言接口賦值實例介紹”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。