英文:
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 struct
s 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) {
// 任意三个结构体之一
}
英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论