如何遍历不同结构类型的值并在每个上调用相同的方法?

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)。我如何在一个循环中同时动态地运行这些方法?


也许我需要一个接口。我不知道。


慕勒3428872
浏览 77回答 2
2回答

临摹微笑

使用 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())}

慕尼黑8549860

这实际上是两个问题:如何创建接口,以及如何同时运行一些东西。定义接口很简单:type Shape interface {&nbsp; &nbsp; Area() float64}由于 Go 的魔力,每个Area() float64定义了函数的类型都会自动实现这个接口。多亏了这个接口,我们可以将多个形状放入一个切片中:&nbsp; &nbsp; shapes := []Shape{&nbsp; &nbsp; &nbsp; &nbsp; Rect{5.0, 4.0},&nbsp; &nbsp; &nbsp; &nbsp; Circle{5.0},&nbsp; &nbsp; }循环这个很容易:&nbsp; &nbsp; for _, shape := range shapes {&nbsp; &nbsp; &nbsp; &nbsp; // Do something with shape&nbsp; &nbsp; }同时打印该区域确实不是您想要做的事情。它提供了不可预测的输出,其中多行可能混合在一起。但是让我们假设我们同时计算这些区域,然后在最后打印它们:&nbsp; &nbsp; areas := make(chan float64)&nbsp; &nbsp; for _, shape := range shapes {&nbsp; &nbsp; &nbsp; &nbsp; currentShape := shape&nbsp; &nbsp; &nbsp; &nbsp; go func() { areas <- currentShape.Area() }()&nbsp; &nbsp; }&nbsp; &nbsp; for i := 0; i < len(shapes); i++ {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Area of shape = %0.2f\n", <-areas)&nbsp; &nbsp; }注意我们必须如何currentShape在循环内捕获局部变量,以避免它在 goroutine 有机会运行之前改变 goroutine 内的值。还要注意我们如何不使用for area := range areas来消耗通道。这将导致死锁,因为在将所有区域写入通道后通道并未关闭。还有其他(也许更优雅)的方法来解决这个问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go