为了账号安全,请及时绑定邮箱和手机立即绑定

函数类型与单一方法接口

函数类型与单一方法接口

Go
BIG阳 2021-11-01 11:00:28
如果接口只有一个方法,我应该使用函数类型吗?以下是这两种方法的示例:type Delegate interface {                 | type Delegate func(x int) int  Do(x int) int                           | }                                         |                                           | type App struct {                         | type App struct {  delegate Delegate                       |   delegate Delegate}                                         | }                                          | func (this *App) foo() {                  | func (this *App) foo() {  ...                                     |   ...  y := this.delegate.Do(x)                |   y := this.delegate(x)  ...                                     |   ...}                                         | }                                          | func main() {                             | func main() {  delegate := &DelegateImpl{}             |   delegate := &DelegateImpl{}  app := &App{delegate}                   |   app := &App{delegate.Process}  ...                                     |   ...}                                         | }测试:type FakeDelegate {                       |   t *testing.T                            |   expectedX int                           |   result int                              | }                                         |                                           | func (this *FakeDelegate) Do(x int) int { |   require.Equal(t, this.expectedX, x)     |   return this.result                      | }                                         |                                           | 看起来右边的代码(带有函数类型)的行数较少,尤其是在测试方面。但就没有什么陷阱吗?
查看完整描述

2 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

一般情况下

这是一个设计问题。接口提供了函数所没有的东西:动态调度。因此,如果稍后您希望(可能是您自己的)客户端代码将所述函数应用于对象,并设想该对象可能是程序中某个给定点的几种不同类型之一,请选择接口。

优点:你可以变得灵活。

缺点:

  • 动态分派的执行时间开销很小。例如,您不会希望在关键循环的中间出现这种情况。

  • 接口(如果可用)将随着系统的增长而使用,可能会以稍微出乎意料的方式使用。这意味着虽然大多数时候您可以轻松地定义函数的职责范围,但作为设计决策,接口的职责和类型签名应该经过深思熟虑。

  • 对于试图理解代码的读者来说,还有更多的知识间接要经过。

Go 被设计为一种简单实用的语言。我想作为有意愿的用户,我们应该发扬它的理念。因此,我会说:如果您不需要某些东西,请不要使用它。:)

在您的特定情况下

尽管函数指针确实是开发人员管理的动态调度的一种形式,但在我看来,上述推理仍然适用:寻找可以满足可预见需求的最简单解决方案。否则 Go 将成为 Java。如果您确定委托永远不需要提供任何其他入口点(例如提供元信息),我会说坚持使用函数指针。


查看完整回答
反对 回复 2021-11-01
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

我认为使用以下简单规则是合理的:

  • 如果最有可能的实现适用于未在参数中传递的数据,则使用接口。标准库中的示例:io.Reader具有单个方法的接口Read

  • 否则使用函数。从标准库的例子:http.HandlerFuncbufio.SplitFunc

我还发现好名字有助于设计决策。


查看完整回答
反对 回复 2021-11-01
  • 2 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信