Go语言 函数实现接口与结构实现接口

db2dz4w8  于 2023-04-27  发布在  Go
关注(0)|答案(1)|浏览(120)

在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)
}

// 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()
}

选项#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()
}

两者都可以工作,但似乎函数选项对更改的弹性较低?
有没有一个例子,说明使用函数实现接口比使用结构体更好?或者,在某些情况下使用结构体选项的缺点?

ctzwtxfj

ctzwtxfj1#

你可以在net/httpHandler以及HandlerFunc中看到这一点。满足接口的函数是很方便的-你甚至可以传入闭包:

c := Controller{
    l: LoggerAdapter(func(message string) {fmt.Println(message)}),
}

但是一个函数不能有字段,而且它也很少有额外的有用的方法。像这样的函数类型倾向于有一个单独的方法来调用函数。
如果你需要一个更复杂的类型,那就是结构体,所以你可以使用它。

相关问题