英文:
Prototyping struct in Go
问题
我的用例是,我需要在Go中有几个结构体,它们将具有相同签名的方法,并且不一定必须具有所有方法。以下代码描述了要求,并表示了我的当前解决方案。
type calc struct {
fn func(a, b int) int
gn func(a string) bool
name string
}
func add(a, b int) int {
return a + b
}
func bar(foo string) bool {
// do something
}
func sub(a, b int) int {
return a - b
}
func main() {
for c := range []calc{
{
fn: add,
gn: bar,
name: "addition",
},
{
fn: sub,
name: "subtraction",
},
} {
fmt.Printf("%s(10, 15) returned: %d\n", c.name, c.fn(10, 15))
if c.gn != nil {
c.gn(c.name)
}
}
}
我的问题是如何改进这段代码?在Go中实现这个有什么最佳方式?我能否使用接口实现更好的解决方案?
英文:
My use case is, I need to have several structs in Go, who will have methods of same signatures and not necessarily have to have all the methods. The following code describes the requirements and also represents my current solution.
type calc struct {
fn func(a, b int) int
gn func(a string) bool
name string
}
func add(a, b int) int {
return a + b
}
func bar(foo string) bool {
// do something
}
func sub(a, b int) int {
return a - b
}
func main() {
for c := range []calc{{
fn: add,
gn: bar,
name: "addition",
}, {
fn: sub,
name: "subtraction",
}} {
fmt.Printf("%s(10, 15) returned: %d\n", c.name, c.fn(10, 15))
if c.gn != nil {
c.gn(c.name)
}
}
}
My question is how to improve this code? What's the best way to achieve this in Go? Can I achieve a better solution using interface?
答案1
得分: 4
使用接口。
type Op interface {
Name() string
Do(a, b int) int
}
type Add struct{}
func (Add) Name() string { return "add" }
func (Add) Do(a, b int) int { return a + b }
type Sub struct{}
func (Sub) Name() string { return "sub" }
func (Sub) Do(a, b int) int { return a - b }
Playground: http://play.golang.org/p/LjJt6D0hNF.
编辑: 由于您编辑了您的问题,这里是一个示例,说明如何将接口断言为更广泛的接口以完成您的任务:
type RevOp interface {
Op
ReverseDo(a, b int) int
}
// ...
func (Add) ReverseDo(a, b int) int { return a - b }
// ...
fmt.Printf("%s(10, 15) 返回: %d\n", op.Name(), op.Do(10, 15))
if op, ok := op.(RevOp); ok {
fmt.Printf("反转 %s(10, 15) 返回: %d\n", op.Name(), op.ReverseDo(10, 15))
}
Playground: http://play.golang.org/p/MQ6LlPDcEi.
英文:
Use interfaces.
type Op interface {
Name() string
Do(a, b int) int
}
type Add struct{}
func (Add) Name() string { return "add" }
func (Add) Do(a, b int) int { return a + b }
type Sub struct{}
func (Sub) Name() string { return "sub" }
func (Sub) Do(a, b int) int { return a - b }
Playground: http://play.golang.org/p/LjJt6D0hNF.
EDIT: Since you've edited your question, here is an example of how you could use asserting and interface to a broader interface for your task:
type RevOp interface {
Op
ReverseDo(a, b int) int
}
// ...
func (Add) ReverseDo(a, b int) int { return a - b }
// ...
fmt.Printf("%s(10, 15) returned: %d\n", op.Name(), op.Do(10, 15))
if op, ok := op.(RevOp); ok {
fmt.Printf("reverse of %s(10, 15) returned: %d\n", op.Name(), op.ReverseDo(10, 15))
}
Playground: http://play.golang.org/p/MQ6LlPDcEi.
答案2
得分: 0
我已经与一些人面对面讨论过,显然我的解决方案是正确的。虽然可以使用接口进行重写,但这并不一定是一种改进。
英文:
I've discussed with some people in person and apparently my solution was correct. While it can be rewritten using interface, that's not necessarily an improvement.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论