如何为结构指针上的方法定义接口

How to define interface for methods on struct pointer

对于structs,可以定义一个可以更新struct变量的func。有什么方法可以在 interface?

中使用这些函数吗?

在下面的代码中,我尝试创建一个最小示例来描述我的问题。定义了 RectCircle 中的两个 structstruct 都有 PerimeterExpand 函数。 Perimeter 函数计算形状的周长。 Expand 函数通过改变形状的属性来增加形状的周长。还定义了具有 Perimeter 方法签名的 Shape 接口。

viewShapeData 函数接受 Shape 类型的输入参数。此功能查看形状的数据以及 运行 Perimeter 方法并查看形状的周长。

package main

import "fmt"

type Shape interface {
    Perimeter() float64
}

type Rect struct {
    width  float64
    height float64
}

type Circle struct {
    radius float64
}

func (s Rect) Perimeter() float64 {
    return 2 * (s.width + s.height)
}

func (s Circle) Perimeter() float64 {
    return 2 * 3.14 * s.radius
}

func (s *Rect) Expand(increaseValue float64) {
    s.width += increaseValue / 2
}

func (s *Circle) Expand(increaseValue float64) {
    s.radius += increaseValue / 3.14 / 2
}

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}

    a.Expand(1)
    viewShapeData(a)

    b.Expand(1)
    viewShapeData(b)
}

func viewShapeData(s Shape) {
    fmt.Printf("value: %v, Type: %T, Perimeter: %f\n", s, s, s.Perimeter())
}

现在我正在寻找一种在 viewShapeData 函数中调用 Expand 方法的方法。我尝试了不同的方法并在描述的代码中应用了以下更改:

type Shape interface {
    Perimeter() float64
    Expand(float64)
}

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}

    viewShapeData(a)
    viewShapeData(b)
}

func viewShapeData(s Shape) {
    s.Expand(1)
    fmt.Printf("value: %v, Type: %T, Perimeter: %f\n", s, s, s.Perimeter())
}

但是出现了这些错误:

cannot use a (type Circle) as type Shape in argument to viewShapeData:
        Circle does not implement Shape (Expand method has pointer receiver)
cannot use b (type Rect) as type Shape in argument to viewShapeData:
        Rect does not implement Shape (Expand method has pointer receiver)

请给我一个解决方案或者告诉我为什么Golang不支持这种编码。

因此,如果您想使用指针接收器,您还应该将指针传递给采用接口的函数。

例如

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}
    
    a.Expand(1)
    viewShapeData(&a)

    b.Expand(1)
    viewShapeData(&b)
}

https://play.golang.com/p/pmHd5yl_v8p