为了账号安全,请及时绑定邮箱和手机立即绑定

Golang:代码重复和类似的结构

Golang:代码重复和类似的结构

Go
幕布斯7119047 2021-11-15 15:47:13
Go to superclass 类似(但不相同)的数据类型以最小化代码重复的惯用方法是什么?老生常谈的例子:import "time"type LinuxUtmp struct {    ut_type uint16    _       [2]byte    ut_pid  uint32    ut_line [32]byte    ut_id   [4]byte    ut_user [32]byte    ut_host [256]byte    exit_status [2]uint32    tv_sec  uint32    tv_usec uint32    ...}func (l LinuxUtmp) User() string {    return string(l.ut_user[:])}func (l LinuxUtmp) Time() time.Time {    return time.Unix(int64(l.tv_sec), int64(l.tv_usec))}type BsdUtmp struct {    ut_line [8]char    ut_name [16]char    ut_host [16]char    ut_time uint32}func (b BsdUtmp) User() string {    return string(b.ut_user[:])}func (b BsdUtmp) Time() time.Time {    return time.Unix(int64(b.ut_time), 0)}显然还有更多的东西,但我希望能够以某种方式超类那些,所以我只需要编写和维护特定函数的一个副本。接口似乎是“正确”的方式,但这还有很多不足之处(非工作示例):type Utmp interface {    Time() time.Time}func User(u Utmp) string {    return string(u.ut_user[:])}我也考虑过嵌入,但这似乎也是一个死胡同,因为 Go 的类型如此严格。我是否注定要拥有除签名外在各方面都相同的多段代码?[编辑]部分复杂之处在于我使用 encoding/binary.Read() 根据字节序解析这些数据(不仅仅是 utmp 记录,而不仅仅是 Linux/BSD)。要使用它,字段必须按照它们在磁盘上的精确顺序在结构中[导出]。因此我不能只嵌入另一个结构的字段,因为在某些记录中它们的顺序不同(并且大小不同)
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超12个赞

我不明白您对嵌入的评论。这是我的方法(使用嵌入):


package test


import "time"


type Utmp struct {

    // Common fields

}


func (u Utmp) User() {

    return string(l.ut_user[:])

}


type LinuxUtmp struct {

    Utmp

    // Linux specific fields

}


func (l LinuxUtmp) Time() time.Time {

    return time.Unix(int64(l.tv_sec), int64(l.tv_usec))

}


type BsdUtmp struct {

    Utmp

    // BSD specific fields

}


func (b BsdUtmp) Time() time.Time {

    return time.Unix(int64(b.ut_time), 0)

}

任何导入库的代码都可以User()直接调用方法LinuxUtmp和BsdUtmp对象,l.User()无论b.User()是否提及Utmp。如果您愿意,您甚至可以保留Utmp出乎意料的 (as utmp)。


查看Effective Go了解详情。


如果您愿意,您甚至可以确保只有适用于相关平台的代码才能在二进制文件中编译。这个博客有一些例子。为了保持简单,如果特定于平台的代码不是很大或涉及其他因素,我不会费心走这条路。


为了完整起见,这里是官方的go build文档。


查看完整回答
反对 回复 2021-11-15
?
烙印99

TA贡献1829条经验 获得超13个赞

如果遇到某些东西类型不一样的问题,可以让TimeUser函数运行在一个封装了linux和bsd功能的接口上。

如果您不喜欢那样,您可以生成代码以避免重复。


查看完整回答
反对 回复 2021-11-15
  • 2 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信