在Go中,我们可以创建实现接口的函数,如http.Handler接口和具体类型http.HandlerFunc.我创建了另一个这种模式的简单示例来计算不同员工的 prize .


type BonusCalculator interface {
    Calculate(salary float64) float64
}

type BonusFunc func(salary float64) float64

func (bonus BonusFunc) Calculate(salary float64) float64 {
    return bonus(salary)
}

var (
    DeveloperBonus BonusFunc = func(salary float64) float64 { return salary*1.5 + 2500.00 }
    ManagerBonus   BonusFunc = func(salary float64) float64 { return salary * 2.0 }
    DirectorBonus  BonusFunc = func(salary float64) float64 { return salary * 3.3 }
)

func CalculateBonus (bonus BonusCalculator, salary float64) float64 {
  return bonus.Calculate(salary)
}

func main() {
    bonus := CalculateBonus(DirectorBonus, 35000.00)
    fmt.Printf("bonus %.2f", bonus)
}


因此,上面我们用简单的BonusFuncs实现了接口BonusCalculator,而不是使用 struct 来做同样的事情.

这种图案有名字吗?我在很多地方看到它,但从来没有找到它的名字.

推荐答案

这种图案有名字吗?我在很多地方看到它,但从来没有找到它的名字.

是的,这个模式被称为Adapter,因为它允许某种"接口"(在本例中为闭包)用作另一种接口(满足BonusCalculator的类型).

在您的示例中,您有一个接口BonusCalculator:

type BonusCalculator interface {
    Calculate(salary float64) float64
}

然而,您有类型为func(salary float64) float64的闭包,并且您希望能够在需要满足BonusFunc的类型时传递它们,即具有方法Calculate(salary float64) float64的类型(闭包没有具有这种名称的方法,因此它们不满足BonusCalculator).

你想要的是从func(salary float64) float64BonusCalculatoradapt.因此,您定义了一个新类型BonusFunc,它是adapter.它将从您想要适应的闭包类型派生,并通过在其上定义一个简单地调用底层闭包的方法Calculate(salary float64) float64来满足BonusCalculator:

type BonusFunc func(salary float64) float64

func (bonus BonusFunc) Calculate(salary float64) float64 {
    return bonus(salary)
}

BonusFuncAdapter;它的存在只是为了适配func(salary float64) float64,从而可以满足接口BonusCalculator的要求.现在,无论何时将func(salary float64) float64赋给BonusFunc,您都会获得一个满足Bonuscalculator的值.

Go相关问答推荐

验证访问令牌(密钥罩)

Go SQLCMD比Windows本机版本慢吗?

Date.Format正在输出非常奇怪的日期

在整个SQL事务中将使用上下文作为默认设置吗?

理解Golang中的IOTA和常量

从MySQL/GO表获取行数据

Go 中将 int 切片转换为自定义 int 切片指针类型的函数

在多个 struct 体中重用 Go 中的函数

启动套接字服务器会干扰 gRPC/http 客户端服务器通信 Golang

Golang和Gin web框架在router.Run()之后执行代码

使用Cookie身份验证的Gorilla Golang Websocket优化

AWS Lambda 中的 Websocket URL 超时达到错误

使用 LINQ 对内部数组进行排序

当填充通道的函数调用未嵌入 goroutine 时,为什么我会遇到死锁?

如何确定作为函数参数传递的指针是否正在被修改或副本是否正在被修改?

为什么 reflect.TypeOf(new(Encoder)).Elem() != reflect.TypeOf(interfaceVariable)?

使用反射在 struct 内迭代切片 struct

Golang 'defer' 导致发送(接收)API 响应延迟

使用不安全的指针从 [] 字符串中获取值

如何使用 context.WithCancel 启动和停止每个会话的心跳?