You need to enable JavaScript to run this app. Go实现接口时应选择方法接收者还是入参传递所需数据?
优惠活动
大模型
产品
解决方案
定价
更多

Go实现接口时应选择方法接收者还是入参传递所需数据?

Go 接口实现中接收者传值与方法参数传值的选型

这两种写法没有绝对的优劣,分别匹配不同的业务抽象目标,适用场景完全不同:

第一种写法(数据存放在接收者结构体)的适用场景

当 BankAccount 本身就是你业务中的 核心实体,UserId、AccountName、BankName 是该实例的 固有绑定属性 时,这种写法更加合理:

  • 符合面向对象封装的核心思想:实例自身持有状态,方法直接操作实例属性,不需要每次调用都重复传递相同参数
  • 接口通用性更高:无参的 CheckBankAccount() 符合 Go 「小接口」的设计哲学,后续如果有其他类型的账户(比如信用卡账户、对公账户)需要实现校验能力,只需要各自持有对应属性、实现该方法即可,不需要修改接口签名
  • 你提到的「隐藏细节、需要查看实现才知道用到哪些参数」是抽象的正常效果:IBankAccount 接口要表达的语义就是「实现该接口的实例可以完成自身账户的校验」,调用方不需要关心校验逻辑用到了哪些属性,只要知道调用方法就能完成对应操作即可。

你给出的示例调用逻辑也符合业务直觉:一个账户实例自己校验自己的合法性,逻辑通顺。

第二种写法(数据通过方法参数传递)的适用场景

这种写法本身没有问题,你觉得它像普通函数的别扭感,根源是给无状态的结构体命名为 BankAccount 不符合语义。当这个结构体本质是 无状态的业务逻辑处理器 (比如重命名为 BankAccountChecker 就非常合理)时,这种写法完全适用:

  • 处理器本身不需要持有任何状态,只是提供通用的校验逻辑,每次调用传入动态的校验参数即可
  • 适合校验逻辑和具体账户实例解耦的场景:比如你需要批量校验一批来自第三方的账户数据,不需要逐个构造 BankAccount 实例,直接传入参数调用即可。

快速选型判断标准

你可以根据两个特征快速判断用哪种写法:

  • 如果对应数据是 实例的固有属性,会被同一个实例的多个方法复用,就把数据放到接收者结构体中
  • 如果对应数据是 每次调用的动态参数,和处理器实例本身无关,就把数据放到方法参数中

另外补充 Go 通用编码惯例:接口不需要加 I 前缀,直接命名为 BankAccount 即可,Go 不推荐使用匈牙利命名法。


内容的提问来源于stack exchange,提问作者sswastioyono18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 07:33:02