对于给定的接口,我有三个实现。这三个实现如何共享同一个方法?

huangapple go评论72阅读模式
英文:

For a given interface, I have three implementations. How the three implementation share a same method?

问题

我有一个接口:

type Reader interface {
    // 读取 IV 和 Master header
    ReadMaster(p []byte, full bool) (int, error)

    // 读取 User header
    ReadUser(p []byte, full bool) (int, error)

    // 读取 Content 数据
    ReadContent(p []byte) (int, error)
}

我有三个与该接口兼容的结构体。这三个结构体都有相同的 ReadUser 方法。所以我需要这样做:

func (r *s1) ReadUser(buf []byte, full bool) (int, error) {
    //.... 代码 1 ....
}
func (r *s2) ReadUser(buf []byte, full bool) (int, error) {
    //.... 代码 2 ....
}
func (r *s3) ReadUser(buf []byte, full bool) (int, error) {
    //.... 代码 3 ....
}

然而,上面的 "代码1"、"代码2" 和 "代码3" 是完全相同的。有没有一种好的方法来减少重复的代码?例如,定义函数一次,然后将其分配给三个结构体?

英文:

I have an interface:

type Reader interface {
	// Read IV and Master header
	ReadMaster(p []byte, full bool) (int, error)

	// Read User header
	ReadUser(p []byte, full bool) (int, error)

	// Read Content data
	ReadContent(p []byte) (int, error)
}

And I have three structs are compatible with the interface. All the three structs have the samve method ReadUser. So I have to do:

func (r *s1) ReadUser(buf []byte, full bool) (int, error) {
//.... code 1 ....
}
func (r *s2) ReadUser(buf []byte, full bool) (int, error) {
//.... code 2 ....
}
func (r *s3) ReadUser(buf []byte, full bool) (int, error) {
//.... code 3 ....
}

However, the "code1", "code2" and "code3" above are exactly the same. It's there a good way to reduce the duplicate codes? E.g. define the function once and assign it to three struct?

答案1

得分: 7

将其包装在自己的类型中。同时要记住,在Go语言中,接口应该只为小而具体的任务提供契约。一个接口只包含一个方法是非常常见的。

type UserReader interface {
    ReadUser(p []byte, full bool) (int, error)
}

type UserRepo struct {
}

func (ur *UserRepo) ReadUser(p []byte, full bool) (int, error) {
    // 读取用户的代码
}

type s1 struct {
    *UserRepo
    // 其他的内容在这里...
}

type s2 struct {
    *UserRepo
    // 其他的内容在这里...
}

type s3 struct {
    *UserRepo
    // 其他的内容在这里...
}

u := s1{}
i, err := u.ReadUser(..., ...)

u2 := s2{}
i2, err2 := u2.ReadUser(..., ...)

// 等等...

doStuff(u)
doStuff(u2)

func doStuff(u UserReader) {
    // 任意三个结构体之一
}

点击这里在 Playground 中查看示例

英文:

Wrap it in its own type. Remembering too that interfaces in Go should only provide contracts for small specific tasks. It is very common for an interface to contain only a single method.

type UserReader interface {
    ReadUser(p []byte, full bool) (int, error)
}

type UserRepo struct {
}

Add the method to that type:

func (ur *UserRepo) ReadUser(p []byte, full bool) (int, error) {
    // code to read a user
}

Then, embed it in your other types:

type s1 struct {
    *UserRepo
    // other stuff here..
}

type s2 struct {
    *UserRepo
    // other stuff here..
}

type s3 struct {
    *UserRepo
    // other stuff here..
}

Then you can:

u := s1{}
i, err := u.ReadUser(..., ...)

u2 := s2{}
i2, err2 := u2.ReadUser(..., ...)

// etc..

..and you can also do:

doStuff(u)
doStuff(u2)

.. where doStuff is:

func doStuff(u UserReader) {
    // any of the three structs
}

<kbd>Click here to see it in the Playground</kbd>

huangapple
  • 本文由 发表于 2014年10月2日 11:34:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/26154145.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定