Go 中的 7 个常见接口错误

Go 仍然是一门新语言,如果你正在使用它,它很可能不是你的第一门编程语言。

不同的语言,既为你带来了经验,也带来了偏见。你用以前的任何语言做的事情,在 Go 中用相同的方法可能不是一个好主意。

学习 Go 不仅仅是学习一种新的语法。这也是学习一种新的思维方式来思考你的程序:

Go is a language for writing Go programs, not Java programs or Haskell programs or any other language’s programs. You need to think a different way to write good Go programs. But that takes time and effort, more than most will invest. So the usual story is to translate one program from another language into Go and see how it turns out. But translation misses idiom. A first attempt to write, for example, some Java construct in Go will likely fail, while a different Go-specific approach might succeed and illuminate. After 10 years of Java programming and 10 minutes of Go programming, any comparison of the language’s capabilities is unlikely to generate insight, yet here come the results, because that’s a modern programmer’s job.

Rob Pike Esmerelda’s Imagination

正如 Rob Pike 所建议的那样,如果你想提高围棋技能,需要投入时间和精力来学习这门语言的习语。

Go 在几件事上与其他传统语言不同,在本文中,我将重点介绍其中之一:接口。

下面列出了人们在编写 Go 接口时常犯的错误。这些在其他语言中可能不是错误,但在 Go 中,你需要忘记它们。或者至少,给一个机会,暂时不和他们一起工作,看看这会把你引向何方。

但在这之前

以下是阅读本文时要记住的事项列表。如果你已经熟悉它们,请随意跳过。

  • 接口隔离原则:不应强制客户端实现它不使用的接口,也不应强制客户端依赖于它们不使用的方法。

  • 多态性:一段代码根据它收到的具体数据改变其行为。

  • Liskov 替换原则:如果你的代码依赖于抽象,那么一个实现可以被另一个实现替换,而无需更改你的代码。

    抽象的目的不是模糊不清,而是创造一个新的语义层次,在这个层次上可以绝对精确。— E.W.迪克斯特拉

接口是精确包含用于编写程序的想法的概念。

以正确的方式使用接口可以带来简单性、可读性和 organic code 设计。

organic code 是代码会根据你在某个时间点所需的行为而增长。它不会强迫你提前考虑你的类型以及它们之间的关系,因为你很可能无法正确理解它们。

这就是为什么说 Go 偏爱组合而不是继承。你有一小组行为,你可以从中编写任何你想要的,而不是预定义由其他类型继承的类型并希望它们适合问题域。

Rob Pike 在 golang-nuts 论坛上解释了这种方法:

img

Go 的接口不是 Java 或 C# 接口的变体,它们远不止于此。它们是大规模编程和适应性强的演进设计的关键。

无论如何,理论已经足够了,让我们来看看最常见的错误:

1. 你创建了太多的接口

接口过多的术语称为接口污染 interface pollution.。当你在编写具体类型之前开始抽象时,就会发生这种情况。由于你无法预见你需要什么抽象,所以很容易写出太多的接口,这些接口在以后要么是错误的,要么是无用的。

Rob Pike 有一个很好的指南,可以帮助我们避免界面污染:

Don’t design with interfaces, discover them.

Rob Pike

Rob 在这里指出的是,你不需要提前考虑你需要什么抽象。你可以使用具体结构开始设计,并仅在设计需要时创建接口。通过这样做,你的代码会顺其自然的增长到预期的设计。

我仍然看到人们提前创建接口,因为他们认为他们将来可能需要多个实现。

我对他们说:

img

以一种好的方式懒惰。创建接口的最佳时机是你真正需要它的时候,而不是你预测需要它的时候。下面是一个通过提前思考创建接口的示例,以及它导致了什么。

无用的接口往往只有一个实现。它们只是增加了一个额外的间接级别,迫使程序员在真正想要实现时总是通过它们。

接口是有代价的:这是您在推理代码时需要记住的一个新概念。正如 Djikstra 所说,理想的界面必须是“a new semantic level in which one can be absolutely precise.”。

如果你的代码需要 Box 的概念,仅由 Box 实现的名为 Container 的额外接口没有带来任何好处,除了混淆。

因此,在创建接口之前,先问问自己:接口有多个实现吗?我强调使用了‘有’,因为‘将会有’假设了你能预测未来,而你不能。

2. 你有太多的方法

在 PHP 项目中,看到 10 种方法接口是很常见的。在 Go 中,接口很小,标准库中所有接口上的平均方法数为 2。

The bigger the interface the weaker the abstraction,这是 Go 谚语之一。正如 Rob Pike 所说,这是接口最重要的一点,这意味着接口越小,它就越有用。

接口可以拥有的实现越多,它的通用性就越强。如果你有一个包含大量方法的接口,则很难有它的多个实现。您拥有的方法越多,接口就越具体。它越具体,不同类型显示相同行为的可能性就越低。

有用接口的一个很好的例子是

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14589.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI实践】Cursor上手-跑通Hello World和时间管理功能

背景 学习目的:熟悉Cursor使用环境,跑通基本开发链路。 本人背景:安卓开发不熟悉,了解科技软硬件常识 实践 基础操作 1,下载安装安卓Android Studio 创建一个empty project 工程,名称为helloworld 2&am…

存储系统、网盘系统的访问留痕

一、适用场景 1、需要了解是否存在非法访问存储系统或网盘系统:各企业或单位为方便远程办公或远程管理,若自建(保护隐私数据或敏感资料)了存储系统或网盘系统,那么到底有哪些ip地址或用户从远程公网访问存储系统或网盘…

求助DeepSeek帮我开发一个直线审批流程设计页面Vue2.0

之前使用文心一言协助开发过类似的页面,需求方认为某些业务表单需要添加审批流程,可以人为设置审批步骤,由于需求很模糊而且人/天有限,当时的提问很混乱,内容如下: 我的vue2.0系统中需要审批流程设计页面&a…

初级数据结构:栈和队列

目录 一、栈 (一)、栈的定义 (二)、栈的功能 (三)、栈的实现 1.栈的初始化 2.动态扩容 3.压栈操作 4.出栈操作 5.获取栈顶元素 6.获取栈顶元素的有效个数 7.检查栈是否为空 8.栈的销毁 9.完整代码 二、队列 (一)、队列的定义 (二)、队列的功能 (三&#xff09…

LLM:DeepSeek 系列(二)

原文链接 3、DeepSeek-V2 DeepSeek-V2 发布于 2024 年 5 月,为多领域专家(MoE)语言模型,包含总共 2360 亿个参数,其中每个词元激活 210 亿个参数,并支持 12.8 万个词元的上下文长度。DeepSeek-V2 采用包括…

【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)

重要信息 官网:www.cnsse.org 时间:2025年2月21-23日 地点:中国-青岛 简介 第五届计算机网络安全与软件工程(CNSSE 2025)将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…

开源项目介绍-词云生成

开源词云项目是一个利用开源技术生成和展示词云的工具或框架,广泛应用于文本分析、数据可视化等领域。以下是几个与开源词云相关的项目及其特点: Stylecloud Stylecloud 是一个由 Maximilianinir 创建和维护的开源项目,旨在通过扩展 wordclou…

Docker基础以及单体实战

Docker 一、Docker1.1 Docker组成1.2 Dcoker运行图1.3 名称空间Namepace 1.4 docker、Docker compose、kubermetes 二、Docker安装2.1 在线Docker安装2.2 使用官方通用安装脚本2.3 二进制安装Docker三、Docker基础命令3.1 启动类3.2 镜像类3.3 容器类3.4 网络类3.5 Docker comp…

2025年日祭

本文将同步发表于洛谷(暂无法访问)、CSDN 与 Github 个人博客(暂未发布) 本蒟自2025.2.8开始半停课。 任务计划(站外题与专题) 数了一下,通过人数比较高的题,也就是我准备补的题&a…

UIAbility 生命周期方法

生命周期流程图 UIAbility的生命周期官方文档地址https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/uiability-lifecycle-V13 1. onCreate(want: Want, launchParam: LaunchParam) 触发时机:Ability首次创建时 作用:初始化核心资源…

模型 冗余系统(系统科学)

系列文章分享模型,了解更多👉 模型_思维模型目录。为防故障、保运行的备份机制。 1 冗余系统的应用 1.1 冗余系统在企业管理中的应用-金融行业信息安全的二倍冗余技术 在金融行业,信息安全是保障业务连续性和客户资产安全的关键。随着数字化…

【大数据技术】Spark分布式实现词频统计(hadoop+python+spark)

Spark分布式实现词频统计(hadooppythonspark) 搭建完全分布式高可用大数据集群(VMwareCentOSFinalShell) 搭建完全分布式高可用大数据集群(HadoopMapReduceYarn) 本机PyCharm远程连接CentOS虚拟机&#x…

28.<Spring博客系统⑤(部署的整个过程(CentOS))>

引入依赖 Spring-boot-maven-plugin 用maven进行打包的时候必须用到这个插件。看看自己pom.xml中有没有这个插件 并且看看配置正确不正常。 注&#xff1a;我们这个项目打的jar包在30MB左右。 <plugin><groupId>org.springframework.boot</groupId><artif…

C++Primer学习(2.2)

2.2 变量 变量提供一个具名的、可供程序操作的存储空间。C中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围&#xff0c;以及变量能参与的运算。对C程序员来说,“变量(variable)”和“对象(object)”一般可以互换使用。 术…

电脑开机提示按f1原因分析及终极解决方法来了

经常有网友问到一个问题&#xff0c;我电脑开机后提示按f1怎么解决&#xff1f;不管理是台式电脑&#xff0c;还是笔记本&#xff0c;都有可能会遇到开机需要按F1&#xff0c;才能进入系统的问题&#xff0c;引起这个问题的原因比较多&#xff0c;今天小编在这里给大家列举了比…

Linux系统命令无法使用(glib库相关问题)

1.背景描述 Yum强制安装了一些软件&#xff0c;安装软件成功无报错&#xff0c;完成后不久突然发现系统出问题了&#xff0c;所有的命令无法使用了&#xff0c;如ls、mv、cat等基本命令报错。 relocation error&#xff1a; /lib64/libpthread.so.0: symbol_libc_dl_error_tsd …

Jupyter Notebook自动保存失败等问题的解决

一、未生成配置文件 需要在命令行中&#xff0c;执行下面的命令自动生成配置文件 jupyter notebook --generate-config 执行后会在 C:\Users\用户名\.jupyter目录中生成文件 jupyter_notebook_config.py 二、在网页端打开Jupyter Notebook后文件保存失败&#xff1b;运行代码…

【含文档+PPT+源码】基于Python校园跑腿管理系统设计与实现

项目介绍 本课程演示的是一款基于Python校园跑腿管理系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.…

TypeScript 中的联合类型:灵活的类型系统

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

WebStorm设置Vue Component模板

下载vue.js插件 下面有模板样例 Composition API&#xff1a;这是 Vue 3 的一项新特性&#xff0c;允许通过 setup 函数来组织组件逻辑。Options API&#xff1a;这是 Vue 2 和 Vue 3 都支持的传统方式&#xff0c;通过定义组件的 data、methods、computed 等来组织逻辑。 Comp…