日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go語言學習之接口使用的示例詳解_Golang

作者:孫琦Ray ? 更新時間: 2022-12-22 編程語言

正如前文提到,Go語言并沒有類的定義,接口可以說Go語言最接近于類的實現方式,但是更輕量。對于接口的學習,如果從原理層面理解學習起來比較慢,所以建議先從代碼使用維度進行理解,最終回歸到原理層面加深理解。

需求與分析

假設我們有一組圖形,需要計算每個圖形的面積,并計算他們的面積之和。那么最簡單的方法就是分別計算他們的面積,并進行相加,我們來嘗試實現一下。

不使用接口的實現

在這個代碼實現中,我們需要將兩種不同形狀,矩形(rect)和圓形(circle)的面積求和,因此我們定義了如下內容:

  • 兩個結構體,矩形是長和寬,圓形是半徑
  • 分別實現了兩個求面積的方法area(),矩形的面積等于長乘以寬,而圓形面積則是半徑的平方乘以Pi
  • 在求和部分,我們直接定義了一個float64的數組,將面積直接存入該數組中
  • 通過循環進行求和

雖然上述方式能夠滿足我們的需求,但是如果我們需要增加一個計算周長的方法時,我們的代碼會變得非常冗余并且可讀性變差,因此我們用接口嘗試來改造我們的代碼。

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)
}

使用接口的實現

相較于上述代碼,我們做了如下優化:

  • 定義了一個新的interface shape,包含一個area()方法,即實現了area()的struct,就實現了shape接口
  • 在結構體定義,area()計算部分我們并沒有修改
  • 在主函數中,我們重新定義了一個類型為shape interface的數組,該數組中無須再計算area(),只需要將兩個不通類型存放在該數組中
  • 在循環過程中,我們直接調用每個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)
}

接口作為函數參數

進一步優化代碼,我們將接口作為參數,在主函數中調用時,只需要傳入相應類型就會自動根據類型調用相應的計算面積的方法。

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)
}

原文鏈接:https://blog.csdn.net/xiaoquqi/article/details/127994399

欄目分類
最近更新