Go Wiki:经验报告
此页面收集了关于 Go 问题的经验报告,这些报告可能会为我们设计这些问题的解决方案提供信息。这些报告应重点关注问题:它们不应重点关注,也不必提出解决方案。要提出解决方案,请参阅提案流程。
我们希望利用这些经验报告来了解人们在编写 Go 时遇到的困难,以帮助我们确定 Go 生态系统未来更改的优先级。(我们不保证会回复这些。如果您需要立即获得有关 Go 的问题的解答,请参阅https://golang.ac.cn/help/获取资源。)
最佳的经验报告会说明:(1)您想做什么,(2)您实际做了什么,以及(3)为什么效果不佳,并通过真实的具体示例来说明这些,理想情况下来自生产使用。请针对您认为最重要的问题撰写这些报告,将它们发布在您自己的博客上,或在 Medium 上,或作为GitHub Gist(对于 Markdown,请使用.md
扩展名),或作为公开可读的 Google 文档,然后在此处链接它们。(演讲视频或幻灯片也欢迎,尽管它们对我们来说不太方便消化。)
如果您没有权限编辑 wiki 以将文章添加到此列表中,请提交问题。
请保持页面整体按章节字母顺序排序(错误处理在日志记录之前,依此类推)。在一个章节内,请保持文章按时间顺序排序。包含每篇文章要点的一句话摘要很有帮助。
根据需要添加新章节。
目录
- 应用和游戏开发
- 并发
- 类型转换
- 上下文
- 声明
- 依赖项
- 文档
- 诊断和调试
- 教育和教学
- 错误处理
- 错误值
- 文件系统
- 泛型
- GoMobile
- 不变性
- 进程间通信
- 大型软件开发
- 字面量
- 日志记录
- 其他/多个
- 模块
- 性能
- 移植
- 切片
- 语法
- 时间
- 工具
- 类型系统
- 类型化的 nil
- 供应商管理
应用和游戏开发
- Paul Ruest,“Go 库对应用和游戏的支持”,2017 年 11 月
- Tad Vizbaras,“在 Go 中构建光学字符识别 (OCR)”,2017 年 12 月
类型转换
- Richard Warburton,“当底层数据结构相同时,是否允许 Go 类型转换?”,2017 年 12 月
并发
- Sergey Kamardin,“一百万个 WebSockets 和 Go,”2017 年 8 月,关于阻塞读取/写入 goroutine 的内存开销。
- Nathaniel J. Smith,“关于结构化并发的说明,或:Go 语句被认为是有害的”,2018 年 4 月。
上下文
- Sam Vilain,“使用 Go 的 context 库使您的日志更有意义,”2016 年 12 月,关于从 context 中提取结构化日志值。
- Jon Calhoun,“context 值的陷阱以及如何在 Go 中避免或减轻它们,”2017 年 2 月。
- Michal Štrba,“Context 应该在 Go 2 中消失,”2017 年 8 月
- Axel Wagner,“为什么 context.Value 重要以及如何改进它,”2017 年 8 月。
- Dave Cheney,“Context 不是用于取消的,”2017 年 8 月。
- Ross Light,“在 Go Cap'n Proto 中取消 I/O,”2018 年 1 月。
- Iman Tumorang,“避免 Golang API 中的内存泄漏,”2018 年 1 月。
声明
- Christophe Meessen,“Go 的简写声明 := 的问题”,2017 年 7 月,关于隐藏变量陷阱和
:=
的明显不一致。 - Brian Will,“Go 的 := 语法在多个目标变量时容易出错”,2017 年 8 月。
依赖项
- Patrick Bohan,“Docker => Moby:Go 依赖项,”2017 年 6 月 28 日。一个新的 Go 团队在依赖项管理方面遇到的困难以及解决这些困难的方法。
- Judson Lester,“[无标题 gist] (https://gist.github.com/nyarly/edb6b7a5e3a762da6a5e2da8f59acf07)",2017 年 8 月。
- David Collier-Brown,“通过回收 Multics 的答案避免 NP 完全问题”,2018 年 9 月。
- Adrian Hesketh “安全漏洞跟踪”,2018 年 1 月。向安全审计员证明代码不包含已知漏洞。
诊断和调试
-
Kevin Burke,“我如何运行基准测试并打印其结果”,如果我不需要这么多 Unix 胶水来运行和打印这些,那就太好了。2017 年 7 月。
-
John Clarke,通过运行一个非常缓慢的{命中测试失败,增加日志记录}循环来追踪间歇性故障(不是竞争条件),方法是运行“do { go test -race } while ( $LASTEXITCODE -eq 0 )”过夜。很多个夜晚。像https://rr-project.org/这样的执行跟踪功能将具有变革意义。2018 年 11 月。
-
guanw
,cmd/trace
和 PySnooper。将cmd/trace
与(更简洁的)Python 跟踪 API 进行比较。2019 年 5 月。
文档
- Kevin Burke,“需要在三个不同的地方添加二进制文件的文档”,2017 年 5 月。
教育和教学
- Carl Kingsford 和 Phillip Compeau,“用于教学的 Go 2.0”。在入门编程课程中使用 Go 的经验。
错误处理
(本节内容关于编写if err != nil
。)
- Andrew Gerrand,“Go 的错误处理,”2011 年 7 月,展示了 Go 错误处理模式。
- Martin Sústrik,“为什么我应该用 C 而不是 C++ 编写 ZeroMQ(第一部分),”2012 年 5 月,讨论了由于错误处理代码远离导致错误的代码而导致的 C++ 异常处理的生产问题。
- Thomi Richards,“错误的问题,”2014 年 3 月,认为代码必须准确记录其返回的错误/可能抛出的异常至关重要。
- Roger Peppe,“热爱你的错误,”2015 年 3 月,讨论了错误处理的习惯用法。
- Bleve,“延迟清理、检查错误和潜在问题,”2015 年 9 月,展示了与 Bleve 搜索中的错误处理和延迟相关的错误。
- Andrew Morgan,“我不喜欢 Go 中的错误处理的原因以及如何解决它,”2017 年 1 月,关于难以强制执行良好的错误处理、错误没有堆栈跟踪以及错误处理过于冗长。
- André Hänsel,“如果我制作自己的 Go……”,2017 年 8 月
- Peter Goetz,“思考 Go 2 中错误处理的新方法,”2017 年 9 月,展示了 Go 中错误处理的易错性,并列出了改进体验的要求。
错误值
(本节内容关于除了Error() string
方法之外的其他错误语义。)
- Andrew Morgan,“我不喜欢 Go 中的错误处理的原因以及如何解决它,”2017 年 1 月,关于难以强制执行良好的错误处理、错误没有堆栈跟踪以及错误处理过于冗长。
- Chris Siebenmann,“Go 的 net 包没有不透明错误,只有未记录的错误,”2018 年 8 月
- Bryan C. Mills,“Go语言中的错误包装和冗余”,2019年9月
文件系统
- Chris Lewis,“应支持非本地文件系统”,2017年7月。建议将文件系统读取调用替换为更抽象的内容,例如
sql
包所做的那样。
泛型
- “Go泛型讨论总结(动态文档)”。
- Bouke van der Bijl,“Go语言中的惯用泛型”,2014年9月。
- Craig Weber,“在没有泛型的情况下使用Go”,2014年12月。
- Shashank Sharma,“Golang(Go)中的“穷人版”泛型”,2016年5月。
- Niek Sanders,“Go泛型排序的开销”,2016年9月,记录了使用sort.Interface而不是专门代码进行排序的开销。
- Jon Calhoun,“使用代码生成在没有泛型的情况下使用Go”,2017年5月。
- Jon Bodner,“闭包是Go的泛型”,2017年6月
- Andrew Stock,“为什么我想念Go中的泛型”,2017年6月
- Kevin Burke,“包含大量接口转换的代码示例”,需要大量样板/转换代码。
- Ian Lance Taylor,“append函数”,2017年7月。
- DeedleFake,“接口的问题”,2017年7月。
- Kurtis Nusbaum “为什么我对Go如此沮丧”,2017年6月
- Juan Álvarez,“Go标准库中的泛型”,2017年7月。
- David Chase,“Go编译器中Go泛型的用例”,2017年8月
- Varun Kumar,“泛型 - 我希望你在这里……”,2017年8月
- Sameer Ajmani,“泛型Go经验报告:Google指标API”,2017年8月
- Chewxy,“张量重构:Go经验报告”,2017年9月,讨论了泛型的缺乏以及它如何影响为不同数据类型构建高性能多维数组(不得不诉诸大量指针丑陋代码,并手动跟踪类型和运行时类型检查)
- qwerty2501,"由于缺乏泛型导致的运行时错误问题”,2017年10月
- posener,“为什么我建议避免使用go-kit库”,关注点分离需要大量样板代码。gokit尝试使用代码生成来避免这种情况 #70 #308 protoc-gen-gokit,但这看起来像是针对该问题的一个复杂解决方案。
- Xavier Leroy,“模块化模块系统”,关于泛型模块描述的论文。
- Tobias Gustafsson,“实现PEDS的经验”,PEDS是一组静态类型安全、不可变/持久化集合。2017年11月
- 一位谷歌工程师 “govisor/generics.go”。2018年4月27日
GoMobile
- Vijay,“[嵌套结构体和切片在gomobile中不受支持]”
不变性
- Kurtis Nusbaum “为什么我对Go如此沮丧”,2017年6月
- Sindre Myren “Go 2.0:通过权衡特性来保持简洁性” 2017年7月
- Tobias Gustafsson,“实现PEDS的经验”,PEDS是一组静态类型安全、不可变/持久化集合。2017年11月
进程间通信
- Pablo R. Larraondo “Go进程间通信模型”,2017年8月
大型软件开发
- Russ Cox,“代码库重构(借助Go)”,2016年11月,阐述了类型别名部分解决的逐步代码修复问题(#18130)。
- Travis Jeffery,“我更喜欢pkg而不是internal”,2019年11月;讨论Go项目布局、internal存在的问题以及人们使用pkg的原因。
字面量
- Mike Schinkel,“管理字符串字面量很麻烦,不仅在GoLang中,而且在(所有?)其他语言中也是如此”,2022年6月,提出了“字面量字符串”和“字面量模板”类型。
日志记录
- Evan Miller,“日志记录可能很棘手”,2014年9月,展示了日志记录如何增加应用程序尾部延迟。
- Dave Cheney,“让我们谈谈日志记录”,2015年11月,认为只有两个日志级别。
- TJ Holowaychuk,“Apex日志”,2016年1月,描述了一个结构化日志包及其在生产环境中的使用方法。
- Paddy Foran,“Go中的日志记录”,2016年2月,展示了如何将Go程序日志发送到Sentry。
- Martin Angers,“关于可重用包的Go日志记录”,2016年3月,对如何编写不假设特定日志包的代码提出了建议。
- BugReplay.com,“如何将Google Cloud的免费结构化日志记录服务与Golang结合使用”,2016年9月。
- Sam Vilain,“使用 Go 的 context 库使您的日志更有意义,”2016 年 12 月,关于从 context 中提取结构化日志值。
- Logmatic,“Golang日志世界指南”,2017年3月。
- Chris Hines,Peter Bourgon,“提案:标准Logger接口”,2017年2月,与stdlib logger相关的问题,尤其是在库的上下文中,以及一个提出的解决方案。
- Sindre Myren,“log.Fatal与Go无关” 2017年8月,log.Fatal如何与defer配合不佳,以及在Go 1.x和Go 2.x中处理它的简单模式。
- Joonas Loppi,“修复Go日志混乱的一个想法” 2017年12月,只需在任何地方都使用*log.Logger作为接口并在其周围组合解决方案。
其他/多个
- Iman Tumorang,“在Golang上尝试干净架构” 2017年7月
- Laurent Demailly,“我的Go语言体验,第一部分” 2017年12月,从经验丰富的C/C++/Java/脚本语言开发人员的角度列出了当前Go的优缺点。
- Gokcehan Kara,“使用Go语言进行安装可以更简单” 2018年5月,关于使用版本信息的静态剥离二进制文件的安装和分发的一些复杂情况。
- Bob Nystrom,“我期望Go成为的语言” 2010年10月,我希望Go有元组、联合体、构造函数、没有Nil、异常、泛型、一些语法糖,以及从鼻子里喷出芝士威士忌的小马。
模块
- Paul Jolly - “在现有模块中创建子模块” - 涵盖多模块存储库、循环模块依赖项以及在各种“状态”之间切换所需的步骤
- Chi作者 - GitHub评论 - 评论Chi作者为什么推迟实现Go Modules支持(此后已添加)。TL;DR — 由于导入兼容性规则。
- Sam Whited -"支持Go Modules" - 从升级20个模块中学到的经验教训。TL;DR — 将大型模块升级到v1以上非常痛苦,需要工具,模块的故障模式非常复杂,并且很容易在向现有项目添加模块支持时出错。
- Stripe GitHub线程(链接的评论在下) - 恢复Go Modules支持。TL;DR — Stripe正在恢复Go Modules支持,因为对于v1以上的模块,没有明确的从dep升级路径。
- 在
GOPATH
中引用bash脚本 - Badger和Dgraph上的Go Modules。TL;DR - Dgraph正在放弃对v2的支持,因为它迫使非Go模块用户更改其代码。
- 关于Golang依赖管理模式(GOPATH和Go Modules)的调查:现状、问题和挑战。 - 本报告的目的是帮助开发人员更好地了解从GOPATH到Go Modules过渡中的问题。
性能
- Kevin Burke,“真实的Go基准测试”,试图向普通开发人员解释如何使用pprof等工具,也许可以更简单。2016年7月。
- Nathan Kerr,“并发变慢了?”,展示了如何使用Go的测试、基准测试和分析工具来提高函数并发实现的性能。2017年4月。
移植
- Shannon Pekary,“为什么是GOPP”,试图创建一个“class”关键字,该关键字仅使结构体也成为接口,以便更容易地从面向对象的语言移植代码。
切片
- Richard Warburton,“Go 2.0是否应该支持切片比较?”,一个论点,即为了进行相等性比较,将切片视为结构体,忽略后备数组。
- “对切片进行去重过于繁琐”,源代码中的一个10行函数与例如Ruby的
uniq
函数相比。 - “Go可变参数函数的反直觉行为”,2018年1月,在将切片扩展到参数列表时遇到的障碍。
语法
- André Hänsel,“如果我制作自己的 Go……”,2017 年 8 月
- Bojan Zivanovic,“可选函数参数”,2020年5月
- Raanan Hadar,“数据科学家眼中的Go”,2020年9月
时间
- John Graham-Cumming,“闰秒如何以及为何影响Cloudflare DNS”,2017年1月,关于跨闰秒的计时(#12914)。
工具
- Jonathan Ingram,“gofmt不够有主见”,2017年8月,关于开发人员之间关于代码风格的持续争论,因为
gofmt
不够有主见。 - Jean-Laurent de Morlhon,“为什么Maurice绝对不应该用GO编程,从Java开发人员的角度谈论Go(“go dep”不够……),幻灯片是英文的。
类型系统
- Sam Whited,“使用常量和未导出类型伪造枚举类型”,2017年7月,关于尝试使用类型系统来确保提供给API的值的编译时正确性。
- Andreas Matuschek,“操作符方法”,2017年7月,仅仅是为了提醒大家,对于没有对应操作符的类型存在一些问题(#19770)。
- Leigh McCulloch,“Go:指针使用体验报告”,2017年7月,关于指针同时用于传递所有权和指示缺少值的用法。
- Jack Lindamood,“接口包装方法擦除”,2017年7月,关于类型包装导致的信息丢失。
- Sam Whited,“interface{} 的论证”,2017年8月,两个使用 interface{} 的例子,其中一个不好(但必要),另一个很好。
- James Frasché,“求和类型使用体验报告”,2017年8月,由于无法限制为封闭类型集导致的问题。
- Robin Eklind,“具体的用例。针对 James Frasché 的“求和类型使用体验报告””,2017年8月,由于无法限制为封闭类型集导致的问题。
- Rick Branson,“隐式指针 = 明确的坏”,2017年9月,使用接口类型作为参数/变量的隐式引用遇到的问题。
- Chewxy,“张量重构:Go 使用体验报告”,2017年9月,关于 Go 类型系统讨论的问题。
- Walter Schulze,“泛型函数不能作为值传递”,2017年9月。
- Walter Schulze,“对于求和类型:多个返回值被高估了”,2017年9月。
- Nicolas Boulay,“求和类型并不总是最佳选择(类型化的无标签最终解释)”,2017年10月。
- Eduard Urbach,“将 interface{} 类型转换为 chan interface{}”,2017年10月。
- David Vennik,“整理 Golang OOP 原语”,2018年4月20日 - 面向对象编程原语缺乏结构化的问题 - 虚拟函数和冗余的样板类型绑定。
- Jelte Fennema,“通过借鉴 Rust 修复 Go 中的十亿美元错误”,2018年6月14日 - 空指针解引用导致生产环境出现恐慌 - 如果类型系统能够捕获其中的一些错误,那就太好了。
类型化的 nil
- David Cheney,“Go 2 中的类型化 nil”,2017年8月。
供应商管理
- Jeremy Loy,“Go 模块和供应商”,2018年9月。
- Ian Davis,“用于自包含构建的供应商”,2019年1月。
此内容是 Go Wiki 的一部分。