共計(jì) 2745 個(gè)字符,預(yù)計(jì)需要花費(fèi) 7 分鐘才能閱讀完成。
本篇內(nèi)容主要講解“Go 語(yǔ)言接口賦值實(shí)例介紹”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓丸趣 TV 小編來(lái)帶大家學(xué)習(xí)“Go 語(yǔ)言接口賦值實(shí)例介紹”吧!
將對(duì)象實(shí)例賦值給接口
先看看將指定類型的對(duì)象實(shí)例賦值給接口,這要求該對(duì)象對(duì)應(yīng)的類實(shí)現(xiàn)了接口要求的所有方法,這個(gè)是自然,否則也就不能算作實(shí)現(xiàn)該接口了,例如之前我們定義過(guò)一個(gè) 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}
相應(yīng)地,我們定義一個(gè)接口 IntNumber:
type IntNumber interface {Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool Increase(i Integer) Decrease(i Integer)}
安裝 Go 語(yǔ)言的約定,Integer 類型實(shí)現(xiàn)了 IntNumber 接口。然后我們可以這樣將 Integer 類型對(duì)應(yīng)的對(duì)象實(shí)例賦值給 IntNumber 接口:
var a Integer = 1var b IntNumber = a
注意到上述賦值語(yǔ)句中,我們將對(duì)象實(shí)例 a 的指針應(yīng)用賦值給了接口變量,為什么要這么做呢?因?yàn)?Go 語(yǔ)言會(huì)根據(jù)類似下面這樣的非指針成員方法:
func (a Integer) Equal(i Integer) bool
自動(dòng)生成一個(gè)新的與之對(duì)應(yīng)的指針成員方法:
func (a *Integer) Equal(i Integer) bool {return (*a).Equal(i)}
這樣一來(lái),類型 *Integer 就存在所有 IntNumber 接口中聲明的方法,而 Integer 類型不包含指針?lè)椒?Increase 和 Decrease(關(guān)于這一點(diǎn)我們前面已經(jīng)介紹過(guò)),所以嚴(yán)格來(lái)說(shuō),只有 *Integer 類型實(shí)現(xiàn)了 IntNumber 接口。如果我們貿(mào)然將 a 的值引用賦值給 b,編譯時(shí)會(huì)報(bào)錯(cuò):
cannot use a (type Integer) as type IntNumber in assignment: Integer does not implement IntNumber (Decrease method has pointer receiver)
顯然,如果 Integer 類中實(shí)現(xiàn)的方法不是指針?lè)椒ǎ瑒t進(jìn)行接口賦值時(shí),傳遞對(duì)象實(shí)例的值引用給接口變量即可,否則需要傳遞指針變量。為了驗(yàn)證這一點(diǎn),我們可以再創(chuàng)建一個(gè)新的接口 IntNumber2:
type IntNumber2 interface {Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool}
然后將對(duì)象實(shí)例 a 的值引用賦值給 IntNumber 接口變量:
var a Integer = 1varb1IntNumber= avar b2 IntNumber2 = a
則上面兩條接口賦值語(yǔ)句都可以編譯通過(guò)。
將接口賦值給接口
接下來(lái)我們來(lái)看將一個(gè)接口賦值給另一個(gè)接口:在 Go 語(yǔ)言中,只要兩個(gè)接口擁有相同的方法列表(與順序無(wú)關(guān)),那么它們就是等同的,可以相互賦值。
下面我們來(lái)編寫對(duì)應(yīng)的示例代碼,這是第一個(gè)接口 Number1,位于 oop1 包中:
package oop1 type Number1 interface {Equal(i int) bool LessThan(i int) bool MoreThan(i int) bool}
這是第二個(gè)接口 Number2,位于 oop2 包中:
package oop2 type Number2 interface {Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool}
這里我們定義了兩個(gè)接口,一個(gè)叫 oop1.Number1,一個(gè)叫 oop2.Number2,兩者都定義五個(gè)相同的方法,只是順序不同而已。在 Go 語(yǔ)言中,這兩個(gè)接口實(shí)際上并無(wú)區(qū)別,因?yàn)椋?/p>
任何實(shí)現(xiàn)了 oop1.Number1 接口的類,也實(shí)現(xiàn)了 oop2.Number2;任何實(shí)現(xiàn)了 oop1.Number1 接口的對(duì)象實(shí)例都可以賦值給 oop2.Number2,反之亦然;在任何地方使用 oop1.Number1 接口與使用 oop2.Number2 并無(wú)差異。
接下來(lái)我們定義一個(gè)實(shí)現(xiàn)了這兩個(gè)接口的類 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) } func (n Number) MoreThan(i int) bool {return int(n) }
所以下面這些賦值代碼都是合法的,會(huì)編譯通過(guò):
var num1 Number = 1;var num2 oop1.Number1 = num1var num3 oop2.Number2 = num2
此外,接口賦值并不要求兩個(gè)接口完全等價(jià)(方法完全相同)。如果接口 A 的方法列表是接口 B 的方法列表的子集,那么接口 B 可以賦值給接口 A。例如,假設(shè) Number2 接口定義如下:
type Number2 interface {Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool Add(i int)}
要讓 Number 類繼續(xù)保持實(shí)現(xiàn)這兩個(gè)接口,需要在 Number 類定義中新增一個(gè) Add 方法實(shí)現(xiàn):
func (n *Number) Add(i int) {*n = *n + Number(i);}
接下來(lái),將上面的接口賦值語(yǔ)句改寫如下即可:
var num1 oop1.Number = 1;var num2 oop2.Number2 = num1;var num3 oop1.Number1 = num2;
但是反過(guò)來(lái)不行:
var num1 oop1.Number = 1;var num2 oop1.Number1 = num1;var num3 oop2.Number2 = num2; // 這一段編譯出錯(cuò)
因?yàn)?Number1 接口中沒(méi)有 Add 方法,這一點(diǎn)和 PHP/Java 中子類實(shí)例可以直接賦值給父類,而父類實(shí)例不能直接賦值給子類頗有些異曲同工。
到此,相信大家對(duì)“Go 語(yǔ)言接口賦值實(shí)例介紹”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是丸趣 TV 網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!