簡體   English   中英

如何遍歷不同結構類型的值並在每個值上調用相同的方法?

[英]How can I loop over values of different struct types and call the same method on each?

package main

import (
    "fmt"
    "math"
)

type Rect struct {
    width  float64
    height float64
}

type Circle struct {
    radius float64
}

func (r Rect) Area() float64 {
    return r.width * r.height
}

func (c Circle) Area() float64 {
    return math.Pi * c.radius * c.radius
}

func main() {
    rect := Rect{5.0, 4.0}
    cir := Circle{5.0}
    fmt.Printf("Area of rectangle rect = %0.2f\n", rect.Area())
    fmt.Printf("Area of circle cir = %0.2f\n", cir.Area())
}

這是結構的基本常見示例。 但我的問題是如何在多個時運行具有相同名稱的 struct 方法。

在這個例子中,有 2 個結構體。 但是如果有 50 個結構體(Circle, Rect, Foo, Bar ....)並且它們都有一個同名的方法(Area) 我如何同時動態地在循環中運行這些方法?

也許我需要一個接口。 我不知道。

使用帶有 Area 方法的接口切片:

shapes := []interface{ Area() float64 }{Rect{5.0, 4.0}, Circle{5.0}}
for _, shape := range shapes {
    fmt.Printf("Area of %T = %0.2f\n", shape, shape.Area())
}

在 GoLang PlayGround 上運行它

這實際上是兩個問題合二為一:如何創建界面,以及如何並發運行某些東西。

定義接口很簡單:

type Shape interface {
    Area() float64
}

由於 Go 的魔力,每個定義了Area() float64函數的類型都會自動實現這個接口。

多虧了這個接口,我們可以將多個形狀放入一個切片中:

    shapes := []Shape{
        Rect{5.0, 4.0},
        Circle{5.0},
    }

循環這個很容易:

    for _, shape := range shapes {
        // Do something with shape
    }

同時打印的面積真的不是你想要做的事。 它提供了不可預測的輸出,其中多行可能混合在一起。 但是讓我們假設我們同時計算這些區域,然后在最后將它們全部打印出來:

    areas := make(chan float64)
    for _, shape := range shapes {
        currentShape := shape
        go func() { areas <- currentShape.Area() }()
    }
    for i := 0; i < len(shapes); i++ {
        fmt.Printf("Area of shape = %0.2f\n", <-areas)
    }

請注意,我們必須如何在循環內的局部變量中捕獲currentShape ,以避免它在 goroutine 有機會運行之前更改 goroutine 內部的值。

還要注意我們如何不使用for area := range areas來消耗通道。 這會導致死鎖,因為在所有區域都被寫入之后,通道並沒有關閉。 還有其他(也許更優雅)的方法來解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2025 STACKOOM.COM