Go語言學(xué)習(xí)之接口使用的示例詳解
正如前文提到,Go語言并沒有類的定義,接口可以說Go語言最接近于類的實(shí)現(xiàn)方式,但是更輕量。對于接口的學(xué)習(xí),如果從原理層面理解學(xué)習(xí)起來比較慢,所以建議先從代碼使用維度進(jìn)行理解,最終回歸到原理層面加深理解。
需求與分析
假設(shè)我們有一組圖形,需要計(jì)算每個(gè)圖形的面積,并計(jì)算他們的面積之和。那么最簡單的方法就是分別計(jì)算他們的面積,并進(jìn)行相加,我們來嘗試實(shí)現(xiàn)一下。
不使用接口的實(shí)現(xiàn)
在這個(gè)代碼實(shí)現(xiàn)中,我們需要將兩種不同形狀,矩形(rect)和圓形(circle)的面積求和,因此我們定義了如下內(nèi)容:
- 兩個(gè)結(jié)構(gòu)體,矩形是長和寬,圓形是半徑
- 分別實(shí)現(xiàn)了兩個(gè)求面積的方法area(),矩形的面積等于長乘以寬,而圓形面積則是半徑的平方乘以Pi
- 在求和部分,我們直接定義了一個(gè)float64的數(shù)組,將面積直接存入該數(shù)組中
- 通過循環(huán)進(jìn)行求和
雖然上述方式能夠滿足我們的需求,但是如果我們需要增加一個(gè)計(jì)算周長的方法時(shí),我們的代碼會變得非常冗余并且可讀性變差,因此我們用接口嘗試來改造我們的代碼。
package main import ( "fmt" "math" ) type rect struct { width float64 height float64 } func (r rect) area() float64 { return r.width * r.height } type circle struct { radius float64 } func (c circle) area() float64 { return math.Pi * c.radius * c.radius } func main() { var areaSum float64 // Intial circle and rect struct type c1 := circle{2.5} r1 := rect{3, 4} // Save all area results into an array shapeAreas := []float64{c1.area(), r1.area()} // Sum all area together areaSum = 0 for _, area := range shapeAreas { areaSum += area } fmt.Printf("Sum area = %v\n", areaSum) }
使用接口的實(shí)現(xiàn)
相較于上述代碼,我們做了如下優(yōu)化:
- 定義了一個(gè)新的interface shape,包含一個(gè)area()方法,即實(shí)現(xiàn)了area()的struct,就實(shí)現(xiàn)了shape接口
- 在結(jié)構(gòu)體定義,area()計(jì)算部分我們并沒有修改
- 在主函數(shù)中,我們重新定義了一個(gè)類型為shape interface的數(shù)組,該數(shù)組中無須再計(jì)算area(),只需要將兩個(gè)不通類型存放在該數(shù)組中
- 在循環(huán)過程中,我們直接調(diào)用每個(gè)shape interface中的area()方法,即可完成面積求和
package main import ( "fmt" "math" ) // Define a new interface, contain a method define and type is float64 type shape interface { area() float64 } type rect struct { width float64 height float64 } func (r rect) area() float64 { return r.width * r.height } type circle struct { radius float64 } func (c circle) area() float64 { return math.Pi * c.radius * c.radius } func main() { var areaSum float64 // Intial circle and rect struct type c1 := circle{2.5} r1 := rect{3, 4} // Previous: Save all area results into an array // Previous: shapeAreas := []float64{c1.area(), r1.area()} // Define an array with new shape interface shapes := []shape{c1, r1} // Previous: Sum all area together areaSum = 0 // Previous: for _, area := range shapeAreas { // Previous: areaSum += area // Previous: } // Implement a new loop for _, shape := range shapes { areaSum += shape.area() } fmt.Printf("Sum area = %v\n", areaSum) }
接口作為函數(shù)參數(shù)
進(jìn)一步優(yōu)化代碼,我們將接口作為參數(shù),在主函數(shù)中調(diào)用時(shí),只需要傳入相應(yīng)類型就會自動根據(jù)類型調(diào)用相應(yīng)的計(jì)算面積的方法。
package main import ( "fmt" "math" ) // Define a new interface, contain a method define and type is float64 type shape interface { area() float64 } type rect struct { width float64 height float64 } // NOTE: 接口類型為rect func (r rect) area() float64 { return r.width * r.height } type circle struct { radius float64 } // NOTE: 接口類型為circle func (c circle) area() float64 { return math.Pi * c.radius * c.radius } func getArea(s shape) float64 { return s.area() } func main() { var areaSum float64 // Intial circle and rect struct type c1 := circle{2.5} r1 := rect{3, 4} // Previous: Save all area results into an array // Previous: shapeAreas := []float64{c1.area(), r1.area()} // Define an array with new shape interface shapes := []shape{c1, r1} // Previous: Sum all area together areaSum = 0 // Previous: for _, area := range shapeAreas { // Previous: areaSum += area // Previous: } // Implement a new loop for _, shape := range shapes { areaSum += getArea(shape) } fmt.Printf("Sum area = %v\n", areaSum) }
到此這篇關(guān)于Go語言學(xué)習(xí)之接口使用的示例詳解的文章就介紹到這了,更多相關(guān)Go語言接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang異常處理之defer,panic,recover的使用詳解
這篇文章主要為大家介紹了Go語言異常處理機(jī)制中defer、panic和recover三者的使用方法,文中示例代碼講解詳細(xì),需要的朋友可以參考下2022-05-05golang 實(shí)現(xiàn)時(shí)間戳和時(shí)間的轉(zhuǎn)化
這篇文章主要介紹了golang 實(shí)現(xiàn)時(shí)間戳和時(shí)間的轉(zhuǎn)化操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05一文教你如何快速學(xué)會Go的struct數(shù)據(jù)類型
結(jié)構(gòu)是表示字段集合的用戶定義類型。它可以用于將數(shù)據(jù)分組為單個(gè)單元而不是將每個(gè)數(shù)據(jù)作為單獨(dú)的值的地方。本文就來和大家聊聊Go中struct數(shù)據(jù)類型的使用,需要的可以參考一下2023-03-03Go通過goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程
多協(xié)程文件上傳是指利用多線程或多協(xié)程技術(shù),同時(shí)上傳一個(gè)或多個(gè)文件,以提高上傳效率和速度,本文給大家介紹了Go通過goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程,需要的朋友可以參考下2024-05-05Golang 處理浮點(diǎn)數(shù)遇到的精度問題(使用decimal)
本文主要介紹了Golang 處理浮點(diǎn)數(shù)遇到的精度問題,不使用decimal會出大問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02