在golang的接口中是否可以有可选方法?

在golang的接口中是否可以有可选方法?,go,methods,interface,Go,Methods,Interface,我想为接口创建可选的perim方法。有可能吗?就像我不想为三角形创建perim方法,但它给我的错误是缺少一个方法。在接口中可以有可选的方法吗 请告诉我它的替代方案或一些解决方案 type geometry interface { area() float64 perim() float64 } type rect struct { width, height float64 } type triangle struct { base, height float

我想为接口创建可选的perim方法。有可能吗?就像我不想为三角形创建perim方法,但它给我的错误是缺少一个方法。在接口中可以有可选的方法吗

请告诉我它的替代方案或一些解决方案

type geometry interface {
    area() float64
    perim() float64
}

type rect struct {
    width, height float64
}

type triangle struct {
    base, height float64
}

type circle struct {
    radius float64
}

type square struct {
    side float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

func (t triangle) area() float64 {
    return 1 / 2 * t.base * t.height
}

func measure(g geometry) {
    fmt.Println(g)
    switch g.(type) {
    case rect:
        fmt.Println("Rectangles area :", g.area())
        fmt.Println("Rectangle perimeter: ", g.perim())
    case circle:
        fmt.Printf("Circles Area: %.2f\n", g.area())
        fmt.Printf("Circles Perimeter: %.2f\n", g.perim())
    case square:
        fmt.Printf("Area of square: %.2f\n", g.area())
        fmt.Printf("Perimeters of area: %.2f\n", g.perim())
    case triangle:
        fmt.Printf("Area of  triangle: %.2f\n", g.area())
    }
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}
    s := square{side: 7}
    t := triangle{base: 3, height: 4}
    measure(r)
    measure(c)
    measure(s)
    measure(t)
}
规范不允许在类型中使用可选的“标记”方法

请注意,您的实现可能会提供其他方法,而不仅仅是要实现的接口的一部分。可用于检查值的具体类型是否具有“附加”方法,方法是检查它们是否实现了具有这些附加方法的接口类型

在本例中,
FooImpl
只有方法
One()
,但是
Foo2Impl
有方法
One()
Two()

其输出(请在上尝试):

当然,您可以使用以下附加方法创建接口类型:

type Bar interface {
    Two()
}
然后检查它:

if ft, ok := f.(Bar); ok {
    fmt.Printf("%T(%v) has method Two()\n", f, f)
    ft.Two() // You can call it
} else {
    fmt.Printf("%T(%v) doesn't have method Two()\n", f, f)
}

在上尝试此选项。

因为您已经在使用,所以您的参数
g
也可以是空接口:

func measure(g interface{}) {
    fmt.Println(g)
    switch v := g.(type) {
    case rect:
        fmt.Println("Rectangles area :", v.area())
        fmt.Println("Rectangle perimeter: ", v.perim())
    case circle:
        fmt.Printf("Circles Area: %.2f\n", v.area())
        fmt.Printf("Circles Perimeter: %.2f\n", v.perim())
    case square:
        fmt.Printf("Area of square: %.2f\n", v.area())
        fmt.Printf("Perimeters of area: %.2f\n", v.perim())
    case triangle:
        fmt.Printf("Area of  triangle: %.2f\n", v.area())
    }
}
()


它的设计是否合适(OOP的人会不同意),取决于上下文。

根据定义,接口不能有可选的方法;一个可选的方法是无法工作的。如果您有一个接口类型的值,则可以对该值调用在该接口上定义的任何方法。如果一个方法是可选的,你不能假设它是可用的,所以你不能调用它,所以在接口中使用它是没有意义的

但是,您可以只使用多个接口。这在
net/http
包中使用,例如,
ResponseWriter
可能是也可能不是
推送器
;在本例中,
Push
描述了“可选的”
Push
方法,可以通过如下类型的断言访问该方法:

if ok,pusher := resp.(Pusher); ok {
    pusher.Push(...)
}

是的,g是接口,所以我可以使用空接口的概念吗?是的,但我是新的,正在试验golang。
func measure(g interface{}) {
    fmt.Println(g)
    switch v := g.(type) {
    case rect:
        fmt.Println("Rectangles area :", v.area())
        fmt.Println("Rectangle perimeter: ", v.perim())
    case circle:
        fmt.Printf("Circles Area: %.2f\n", v.area())
        fmt.Printf("Circles Perimeter: %.2f\n", v.perim())
    case square:
        fmt.Printf("Area of square: %.2f\n", v.area())
        fmt.Printf("Perimeters of area: %.2f\n", v.perim())
    case triangle:
        fmt.Printf("Area of  triangle: %.2f\n", v.area())
    }
}
if ok,pusher := resp.(Pusher); ok {
    pusher.Push(...)
}