最近由于項(xiàng)目需求,閱讀一些Go語(yǔ)言編寫的項(xiàng)目的源代碼,在某一個(gè)函數(shù)中發(fā)現(xiàn)了一個(gè)奇怪的現(xiàn)象:一個(gè)函數(shù)的返回值類型聲明的是一個(gè)接口的類型,但是實(shí)際在函數(shù)體內(nèi)返回的卻是一個(gè)結(jié)構(gòu)體類型的對(duì)象。
這個(gè)現(xiàn)象對(duì)于新手的我來說很是費(fèi)解。在經(jīng)過一些資料的查閱之后,自己得到了如下的解釋:
一個(gè)結(jié)構(gòu)體實(shí)現(xiàn)了一個(gè)接口,那么函數(shù)中返回值類型為接口時(shí),就應(yīng)該返回這個(gè)結(jié)構(gòu)體。
package main import ( "fmt" ) /** Shape接口定義兩個(gè)函數(shù): area() :計(jì)算面積 circumference() :計(jì)算周長(zhǎng) */ type Shape interface { area() float64 circumference() float64 } //結(jié)構(gòu)體正方形,屬性邊長(zhǎng) type square struct { length float64 } //方法area,由正方形結(jié)構(gòu)體實(shí)現(xiàn) func (s square) area() float64 { sarea := s.length * s.length return sarea } //方法circumference,由正方形結(jié)構(gòu)體實(shí)現(xiàn) func (s square) circumference() float64 { scircumference := s.length * 4 return scircumference } func getarea(len float64) Shape { s := square{ length:4, } fmt.Println("正方形的面積為:",s.area()) fmt.Println("正方形的周長(zhǎng)為:",s.circumference()) return s } func main() { getarea(4) }
package main import ( "fmt" ) /** Shape接口定義兩個(gè)函數(shù): area() :計(jì)算面積 circumference() :計(jì)算周長(zhǎng) */ type Shape interface { area() float64 circumference() float64 } //結(jié)構(gòu)體正方形,屬性邊長(zhǎng) type square struct { length float64 } //方法area,由正方形結(jié)構(gòu)體實(shí)現(xiàn) func (s *square) area() float64 { sarea := s.length * s.length return sarea } //方法circumference,由正方形結(jié)構(gòu)體實(shí)現(xiàn) func (s *square) circumference() float64 { scircumference := s.length * 4 return scircumference } func getarea(len float64) Shape { s := square{ length:4, } fmt.Println("正方形的面積為:",s.area()) fmt.Println("正方形的周長(zhǎng)為:",s.circumference()) return s } func main() { getarea(4) }
這兩個(gè)代碼的區(qū)別就是前者使用了值傳遞,后者使用了指針傳遞。由于這里沒有改變結(jié)構(gòu)體中的屬性值,所以兩種方法在這樣的應(yīng)用場(chǎng)景下,沒有什么區(qū)別,下面來解釋一下這些簡(jiǎn)單的demo:
首先我定義了一個(gè)Shape接口,里面有兩個(gè)待實(shí)現(xiàn)的方法area() :計(jì)算面積 和 circumference() :計(jì)算周長(zhǎng)
然后定義了一個(gè)正方形結(jié)構(gòu)體,里面只有一個(gè)邊長(zhǎng)屬性。
然后使用正方形結(jié)構(gòu)體實(shí)現(xiàn)這個(gè)Shape接口
接著我們就可以進(jìn)入正題,試驗(yàn)我們標(biāo)題的問題了,使用Shape接口類型作為返回值,但是在函數(shù)體內(nèi)實(shí)際的返回值是正方形結(jié)構(gòu)體。
這是Go的一種語(yǔ)法,但實(shí)際的作用或者為是什么這樣寫,我還沒有弄清楚,但是通過以上這個(gè)實(shí)實(shí)在在的例子,關(guān)于為什么返回值類型和實(shí)際返回的不一樣有了一定的理解。
補(bǔ)充:Go語(yǔ)言-結(jié)構(gòu)體和接口
接口中允許嵌套其他接口,效果等同于復(fù)制被嵌套的接口中的方法
當(dāng)前的接口中不允許有與嵌入的接口相同的方法
方法相同的接口相等同
接口不能為空,否則等同于空接口
結(jié)構(gòu)體中的匿名成員內(nèi)的成員和方法會(huì)被嵌套到當(dāng)前結(jié)構(gòu)體中
當(dāng)前結(jié)構(gòu)體中允許有與被嵌套結(jié)構(gòu)體相同的成員和方法,且會(huì)覆蓋被嵌套的結(jié)構(gòu)體的成員和方法
兩個(gè)被嵌套的結(jié)構(gòu)體有相同的成員或方法,會(huì)發(fā)生沖突
有時(shí)候編輯器不會(huì)提示,但會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤
成員名稱和類型完全相同的結(jié)構(gòu)體
如果其中一個(gè)是匿名的,可以直接賦值或判斷相等
類型名不同可以進(jìn)行類型轉(zhuǎn)換,不可以直接賦值或判斷相等
方法的接收器只能是在當(dāng)前包中指定名稱的類型,不能是原生類型、復(fù)合類型、其他包中的類型
重新命名的結(jié)構(gòu)體與原結(jié)構(gòu)體成員完全相同(包括tag),但是沒有原來的方法
一個(gè)類型實(shí)現(xiàn)了接口的所有方法,就是實(shí)現(xiàn)了接口,不管類型和接口之間是否有關(guān)聯(lián)
方法的接收器可以是這個(gè)類型或者這個(gè)類型的指針類型
指針類型的接收器可以被修改成員
非指針類型的實(shí)例直接調(diào)用指針類型接收器的方法,會(huì)遇到無法調(diào)用指針方法,無法獲取地址的問題
指針類型的實(shí)例調(diào)用非指針類型接收器的方法不會(huì)出現(xiàn)問題
將實(shí)例賦值給變量再調(diào)用不會(huì)出現(xiàn)問題
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
標(biāo)簽:雞西 蘭州 重慶 吐魯番 梅河口 汕頭 銅川 欽州
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Go語(yǔ)言-為什么返回值為接口類型,卻返回結(jié)構(gòu)體》,本文關(guān)鍵詞 語(yǔ)言,為什么,返回,值,為,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。