登录
首页 >  Golang >  Go问答

在不同结构之间共享方法实现

来源:stackoverflow

时间:2024-04-25 16:45:33 400浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《在不同结构之间共享方法实现》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

假设我们有 2 个结构体共享一个属性,具有相同的名称和用途,但大小不同:

type (
    l16 struct {
        length uint16
    }

    l32 struct {
        length uint32
    }
)

目标是使这些结构体具有具有完全相同签名和实现的 getlength 方法:

func (h *l16) getlength() int {
    return int(h.length)
}

func (h *l32) getlength() int {
    return int(h.length)
}

——但要避免重复每个结构的实现。

所以我尝试:

type (

    LengthHolder interface {
        GetLength() int
    }

    LengthHolderStruct struct {
        LengthHolder
    }

    L16 struct {
        LengthHolderStruct
        Length uint16
    }

    L32 struct {
        LengthHolderStruct
        Length uint32
    }

)

func (h *LengthHolderStruct) GetLength() int {
    return int(h.Length)
}

- 但 h.length 未定义错误(类型 *lengthholderstruct 没有字段或方法 length)

我们该怎么做?


正确答案


转到 1.17 及以下版本

毫不客气的回答是你不能你不应该。只需在每个结构上实现该方法即可让未来的您和其他维护者感到高兴。

无论如何,假设您绝对必须这样做,当然 embedded 类型对 embedding 类型一无所知,因此您无法从 lengthholderstruct 引用 length .

就我个人而言,我认为 @mh-cbon answer 是一个不错的妥协方案。为了提供替代方案,您可以通过将 length 字段声明为嵌入式结构上的 interface{} 并使用类型开关(在垃圾箱中抛出类型安全),以非常难看的方式解决此问题.

我不会在我的生产系统中使用以下代码,但你可以这样做:

func main() {
    l16 := l16{
        lengthholderstruct: lengthholderstruct{
            length: uint16(200), 
            // but nothing stops you from setting uint32(200)
        },
    }
    fmt.println(l16.getlength())
}

type (
    lengthholder interface {
        getlength() int
    }

    lengthholderstruct struct {
        length interface{}
    }

    l16 struct {
        lengthholderstruct
    }

    l32 struct {
        lengthholderstruct
    }
)

func (h *lengthholderstruct) getlength() int {
    switch t := h.length.(type) {
    case uint16:
        return int(t)
    case uint32:
        return int(t)
    }
    return 0
}

转到 1.18 及更高版本

使用泛型。只要constraint中的类型都可以转换为int,就可以使用以下代码:

type Constraint interface {
     ~uint16 | ~uint32
}

type LX[T Constraint] struct {
    Length T
}

func (h *LX[T]) GetLength() int {
    return int(h.Length)
}

func main() {
    lx := LX[uint16]{
        Length: uint16(200),
    }
    fmt.Println(lx.GetLength()) // 200
}

go演示:https://go.dev/play/p/LYbDrjQkgCN

今天关于《在不同结构之间共享方法实现》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

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