英文:
Function Implementing Interface vs. Struct Implementing Interface
问题
在Go语言中,当实现一个只有一个方法的接口时,何时应该使用函数而不是结构体呢?
假设有一个具有单个方法的日志接口:
type Logger interface {
Log(message string)
}
选项1:使用结构体:
package main
import (
"fmt"
)
type Controller struct {
l Logger
}
func (c Controller) Run() {
c.l.Log("done")
}
type Logger interface {
Log(message string)
}
// 空结构体实现接口的方法
type LoggerImpl struct{}
func (li LoggerImpl) Log(message string) {
fmt.Println(message)
}
func main() {
l := LoggerImpl{}
c := Controller{l: l}
c.Run()
}
选项2:使用函数
package main
import (
"fmt"
)
type Controller struct {
l Logger
}
func (c Controller) Run() {
c.l.Log("done")
}
type Logger interface {
Log(message string)
}
type LoggerAdapter func(message string)
func (lg LoggerAdapter) Log(message string) {
lg(message)
}
func LogOutput(message string) {
fmt.Println(message)
}
func main() {
l := LoggerAdapter(LogOutput)
c := Controller{l: l}
c.Run()
}
两种方法都可以工作,但似乎函数选项对变化的适应性较差。
是否有使用函数来实现接口的示例,比使用结构体更好?或者,在某些情况下使用结构体选项存在哪些缺点?
英文:
When implementing an interface with a single method in Go, when should a function be used vs. a struct?
Contrived example: Say I have a logging interface with a single method:
type Logger interface {
Log(message string)
}
Option 1: Use a Struct:
package main
import (
"fmt"
)
type Controller struct {
l Logger
}
func (c Controller) Run() {
c.l.Log("done")
}
type Logger interface {
Log(message string)
}
// Empty struct with method implementing the interface
type LoggerImpl struct {}
func (li LoggerImpl) Log(message string) {
fmt.Println(message)
}
func main() {
l := LoggerImpl{}
c := Controller{l: l}
c.Run()
}
Option #2 - Use a Function
package main
import (
"fmt"
)
type Controller struct {
l Logger
}
func (c Controller) Run() {
c.l.Log("done")
}
type Logger interface {
Log(message string)
}
type LoggerAdapter func(message string)
func (lg LoggerAdapter) Log(message string) {
lg(message)
}
func LogOutput(message string) {
fmt.Println(message)
}
func main() {
l := LoggerAdapter(LogOutput)
c := Controller{l: l}
c.Run()
}
Both work, but it seems like the function option is less resilient to change?
Is there an example of where using a function to implement an interface is a much better idea than using a struct? Or perhaps, downsides to using the struct option in certain scenarios?
答案1
得分: 1
你可以在net/http
中使用Handler
和HandlerFunc
来实现这一点。满足接口的函数很方便-你甚至可以传递一个闭包:
c := Controller{
l: LoggerAdapter(func(message string) {fmt.Println(message)}),
}
但是函数不能有字段,而且它通常不会有额外有用的方法。像这样的函数类型往往只有一个方法,该方法只是调用函数。
如果你需要一个更复杂的类型,那就是结构体,你可以使用它。
英文:
You see this in net/http
with Handler
and HandlerFunc
. A function that satisfies an interface is convenient - you can pass in a closure even:
c := Controller{
l: LoggerAdapter(func(message string) {fmt.Println(message)}),
}
But a function can't have fields and it's unusual for it to have additional useful methods. Func types like this tend to have a single method that just calls the function.
If you need a more complex type, that's what a struct is, so you can use that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论