登录
首页 >  Golang >  Go问答

Golang:隐含式结构匹配

来源:stackoverflow

时间:2024-02-09 09:09:24 463浏览 收藏

本篇文章给大家分享《Golang:隐含式结构匹配》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

问题内容

考虑这段代码:

type rectangle struct {
    width, height, area int
}

type square struct {
    side, area int
}

type geometry struct {
    area int
}

func sumgeometries(geometries ...geometry) (sum int) {
    for _, g := range geometries {
        sum += g.area
    }
    return
}

func testsumgeometries(t *testing.t) {
    rect := rectangle{5, 4, 20}
    square := square{5, 25}

    got := sumgeometries(rect, square)      // cannot use rect (variable of type rectangle) as geometry value in argument to myfunc compilerincompatibleassign
    want := 45

    if got != want {
        t.error("fail!")
    }
}

我希望 myfunc 采用包含 apple 的任何结构,而不仅仅是具体的 bstruct。

这在 go 中可以实现吗?

我找到 atm 的唯一方法如下:

type Rectangle struct {
    Width, Height, Area int
}

func (r *Rectangle) GetArea() int {
    return r.Area
}

type Square struct {
    Side, Area int
}

func (s *Square) GetArea() int {
    return s.Area
}

type Areaer interface {
    GetArea() int
}

func SumGeometries(geometries ...Areaer) (sum int) {
    for _, s := range geometries {
        sum += s.GetArea()
    }
    return
}

func TestArgs(t *testing.T) {
    rect := Rectangle{5, 4, 20}
    square := Square{5, 25}

    got := SumGeometries(&rect, &square)        // cannot use rect (variable of type Rectangle) as Geometry value in argument to MyFunc compilerIncompatibleAssign
    want := 45

    if got != want {
        t.Error("fail!")
    }
}

这感觉可能不惯用:当我已经对消费者直接访问数据感到满意时,我是否想用不必要的方法污染我的结构?


正确答案


向类型添加方法不会“污染”。

但是有一种方法可以实现您想要的而不需要重复。使用 getarea() 方法定义一个包含公共(此处为 area)字段的 area 类型:

type area struct {
    value int
}

func (a area) getarea() int {
    return a.value
}

并将其嵌入到其他类型中:

type rectangle struct {
    width, height int
    area
}

type square struct {
    side int
    area
}

这样getarea()方法得到promotedrectanglesquare会自动实现areaer。测试一下:

rect := rectangle{5, 4, area{20}}
square := square{5, area{25}}

got := sumgeometries(rect, square)

want := 45

if got != want {
    fmt.println("fail!")
}

不输出任何内容(无错误)。在Go Playground上试试。

请注意,如果 area 仅包含单个字段,您甚至可以省略包装器结构并直接使用 int 作为基础类型:

type area int

func (a area) getarea() int {
    return int(a)
}

那么使用起来就更简单了:

rect := Rectangle{5, 4, 20}
square := Square{5, 25}

拨打 Go Playground 试试这个。

本篇关于《Golang:隐含式结构匹配》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>