[英]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())
}
這實際上是兩個問題合二為一:如何創建界面,以及如何並發運行某些東西。
定義接口很簡單:
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.