Go4 和对 Go 的贡献

发布于:2024-10-17 ⋅ 阅读:(14) ⋅ 点赞:(0)

本篇内容是根据2017年4月份Go4 and Contributing to Go音频录制内容的整理与翻译,

Brad Fitzpatrick 加入节目谈论成为开源 Go 的代言人、让社区参与 bug 分类、Go 的潜在未来以及其他有趣的 Go 项目和新闻。

过程中为符合中文惯用表达有适当删改, 版权归原作者所有.



Erik St. Martin: 好的,大家好,欢迎回到 GoTime 的另一期节目。今天的节目是第 44 期,今天的赞助商是 Toptal 和 DataDog。

今天的节目嘉宾有我自己,Erik St. Martin,还有 Carlisia Pinto ---打个招呼吧,Carlisia。

Carlisia Thompson: 大家好。

Erik St. Martin: 还有 Brian Ketelsen

Brian Ketelsen: 大家好!

Erik St. Martin: 我们今天的特别嘉宾大概不用多做介绍了,他是 Go 团队的一员---Brad Fitzpatrick。

Brad Fitzpatrick: 大家好!

Erik St. Martin: 嗨 Brad,最近怎么样?

Brad Fitzpatrick: 还不错。

Erik St. Martin: 对那些可能不太了解你的人,你能简单介绍一下你是谁以及你在做什么吗?

Brad Fitzpatrick: 我在 Go 项目上工作大概有 5-6 年了,我主要负责开源项目的部分,包括标准库,我也管理构建系统……这些年我几乎碰过每个部分。

Erik St. Martin: 大家应该感谢你为 HTTP 做了很多贡献吧…

Brad Fitzpatrick: 是的,我负责了很多标准库的部分---我开发了 HTTP 客户端和服务器,支持 HTTP/1 和 HTTP/2…

Brian Ketelsen: 还有 DB SQL…

Brad Fitzpatrick: 对,数据库的部分,还有子进程执行的部分,JSON 的部分我也做了一些…可以说是到处清理。现在 Go 1 已经定型,不能改动太多了,但在 Go 1 之前,变化还是很多的。

Brian Ketelsen: 那时候真是“好时候”啊……

Brad Fitzpatrick: 是啊。

Erik St. Martin: 你提到了一件有趣的事……似乎 Go 团队有些成员专注于解决 Google 内部使用 Go 的问题,另一些则更多地面向外部社区。是这样吗?

Brad Fitzpatrick: 是的,确实如此。早期只有三四个人,后来大概有八九个人,大家都做所有的事情,包括内部和外部的工作。但随着 Go 在 Google 内外的流行度增加,我们开始更多地专注于不同的领域。现在确实有一些人几乎不接触开源社区,他们主要处理 Google 内部的库或性能问题。

有时你会看到他们突然出现在开源世界中,修复一些 bug 或者进行性能优化,这可能是他们第一次出现在公共领域,因为他们之前可能已经在内部调试了好几周。

我们正在努力改变这种情况,让那些只在 Google 内部贡献的人更多地参与开源社区。因为内部和外部的工具和流程不同,所以他们可能会感到不适应。我们打算每三到六个月安排一次,让他们花一两周的时间参与我们称为“启动时间”的活动,当我们为新的 Go 版本开放代码库时,让他们也参与进来。

Brian Ketelsen: 我注意到你几乎成了 Go 开源项目的公共面孔。无论出现什么问题,都是你在处理;仪表盘宕机、构建系统出问题,大家都在找你。这几年来,看到这种情况是如何演变的很有趣。这是你自愿做的吗?还是某种程度上被推选的?

Brad Fitzpatrick: 这事情是渐渐发生的……然后有一天,Russ 或者 Ian 或者某个团队的人正式决定让我来做,我也就接受了,反正我已经基本上在做了。这其实也是 Go 项目中很多事情的运作方式:你做某件事做得久了,就自然而然成了负责人。

Erik St. Martin: 但这也会带来“核心人物”问题,对吧?

Brad Fitzpatrick: 对,这是个现存的问题。其实我很快要迎来我的第一个孩子了,我会休产假。这也是另一种“核心人物”问题吧,但我一直在培养一些人来接手构建系统和仪表盘的管理工作。

Brian Ketelsen: 这是我们听到的最好的消息。

Brad Fitzpatrick: 是啊,这会很有趣……不过我可能会错过 GopherCon,但我觉得这是个不错的理由。

Brian Ketelsen: 没问题,这次我们会原谅你。

Brad Fitzpatrick: 好的。我只是希望能有直播,这样我可以在家里观看。

Brian Ketelsen: 去年就有直播。

Brad Fitzpatrick: 哦,真的吗?

Erik St. Martin: 是的,主会场的所有主题演讲都有直播,分会场的没直播……不过我们还在安排细节,可能今年也会部分直播,所以这次你可以错过。婚礼可以改期,但是孩子的出生不能改。

Brian Ketelsen: 孩子的出生其实是可以计划的。

Carlisia Thompson: Brad,其实你本可以把时间安排得更好。

Brad Fitzpatrick: 我知道……不过我确实把时间安排在了 Go 1.9 发布的时候,所以……[笑] 不知道这是好事还是坏事,不过至少在 1.9 版本冻结期间,我不用太担心。

Erik St. Martin: 那么 1.9 版本的代号会跟你孩子的名字一样吗?

Carlisia Thompson: 是啊,简直是双重“出生”了。

Brad Fitzpatrick: 我们之前的版本没有用代号,所以现在开始用的话会有点奇怪。

Brian Ketelsen: 你们总得从某个地方开始一个传统嘛。别的项目都用代号,比如 Zesty Zephyrs、Xenial Xerces 之类的。我觉得 Go 也该有一些酷炫的名字,这是我们缺少的。

Brad Fitzpatrick: 可以提交个提案,我们有提案流程。

Brian Ketelsen: 好,我去提案……我大概知道会发生什么。

Erik St. Martin: 删除![笑]

Carlisia Thompson: 说到 Brad 处理各种事务,我们来谈谈大家如何为 Go 贡献代码吧……最近 Steve Francia 写了一篇博文,我觉得我们可以在节目里讨论一下。对了,Brad,你能通过我的 pull request 吗?我昨晚刚提交的……拜托啦![笑]

Brad Fitzpatrick: 嗯,实际上我们还没有正式接受 pull requests---这是我接下来要做的一件事。

Carlisia Thompson: 我提交的那是什么?我做了一个修改……叫 CL,它是什么意思?

Brad Fitzpatrick: CL 是 ChangeList 的缩写。这其实是 Perforce 的术语,那时候 Google 还在用 Perforce。

Erik St. Martin: 我记得 Perforce。

Brad Fitzpatrick: Go 项目已经经历了四个版本控制系统,我想 Perforce 是第一个。我们先用 Perforce,然后是 Subversion,再是 Mercurial,现在是 Git。但在这些转换过程中,我们的工具不断更新,以保持和最初的工具相似,所以我们仍然使用那些老旧的术语。这确实很奇怪。

Carlisia Thompson: 好吧,但别转移话题……你能通过我的请求吗?[笑]

Brian Ketelsen: 是的,CL。

Brad Fitzpatrick: 你最好提醒我一下,有时候我会漏掉一些事情,这是我需要改进的。我需要改进我的仪表盘,这样大家都可以帮忙查看旧的请求。现在,遗憾的是,我通常只看到邮箱里最上面的那些。如果你再提醒一下,它就会回到顶部。

Erik St. Martin: 我喜欢 Carlisia 选在直播时让你表态……你在节目里可没法拒绝。

Brian Ketelsen: 太厉害了。

Carlisia Thompson: 我提交的 CL 是为了在网站上加上 GoTime。

Brad Fitzpatrick: 哦,我今天早上确实看到过这个。

Brian Ketelsen: 那是 CL 编号 41146…

Carlisia Thompson: 好的,按下按钮吧。

Erik St. Martin: 她说:“我们等着。” [笑]

Brad Fitzpatrick: 我现在用的是另一台电脑……

Brian Ketelsen: 你真是太棒了,Carlisia。

Carlisia Thompson: 不管怎样,我们还是听听 Brad 怎么说这个过程吧?你之前提到了提交提案的事情……是不是有些情况不需要提交提案?比如,我提交了那个 CL(ChangeList),但当时我是问了 Steve Francia,“嘿,我们能加上这个吗?”他回答说,“可以,提交修改吧。”于是我就提交了。

我没有开一个 issue……如果我没有问 Steve,我是不是应该先开个 issue?还是说对于这种很小的改动,直接提交 CL 就可以了?

Brad Fitzpatrick: 如果改动很小,直接提交就行了。我们甚至让提案的流程尽量简化,因为我们知道,即便我们写了一个非常正式的提案流程,人们也可能会忽略或者不去看。所以我们让提案流程从提交一个 bug 开始,然后开始讨论。如果我们觉得你的提案比较复杂,确实需要更多的正式性,我们才会给你发送提案模板,让你写一个正式的提案。

大多数时候,我们会立即说“可以”或“不可以”,并不会让大家经历整个“写设计文档”的过程。

Carlisia Thompson: 好的。

Brad Fitzpatrick: 是的,你的改动可能没有什么争议。我猜会有人(也可能是我)稍后点击“接受”。

Carlisia Thompson: 谢谢你。实际上,我看到了一段代码,我想加上它,但我自己其实没有什么使用需求……我只是觉得“哇,如果有这个就更完整了”。那我提交提案的时候,是否一定需要有一个强有力的使用场景?还是说即便没有使用场景,我也可以提交,并且说“嘿,我觉得它应该存在”?

Brad Fitzpatrick: 我们有一个我很早前就加上的 FAQ,叫“为什么 X 不在标准库里?”基本上,它解释了我们在标准库里放了太多东西,这其实是个错误,所以除非非常重要的功能,我们不鼓励再往标准库里添加新东西。通常我们会说,“不,请把它放到 GitHub 上。”

Carlisia Thompson: 你说的“放到 GitHub 上”是指什么?

Brad Fitzpatrick: 你刚才说你想加的东西是为了完整性,但你自己并没有使用场景……

Carlisia Thompson: 是的。

Brad Fitzpatrick: 所以如果你提议将这个东西加到标准库,我们可能会说“不”,特别是当没有实际需求,只是为了好玩的时候。我们通常不会仅仅因为可以而往标准库里添加东西。

Carlisia Thompson: 但你刚才说“放到别的地方”是什么意思?

Brad Fitzpatrick: 是的,比如你可以把它放到某个地方,用户可以通过 go get 来获取。标准库的问题在于我们无法快速修复问题,也不能轻易更改或移除东西,所以如果你把它放到 GitHub 上,你会有更多的灵活性。

Carlisia Thompson: 就像我自己的项目一样……

Brad Fitzpatrick: 是的,或者其他地方……你可以自己注册一个域名,给它取个有趣的名字。我有一个 go4.org 网站,上面放着一些我在多个项目中需要的 Go 实用函数,但我并不想把它们加到标准库里……所以我把一些有趣的东西都放到了 go4.org 上。

Carlisia Thompson: 哦,挺酷的。

Erik St. Martin: 我也应该这么做。我很早前就注册了 gopher.af……[笑] 但到现在还没找到用它的机会。

Brad Fitzpatrick: 自从我注册了 go4.org 这个域名之后,我就收到大量垃圾邮件,有人说“嘿,我有一个类似的域名,你有兴趣买吗?” 但那些域名全都很糟糕,全都是随便拼起来的字母和数字。我想,“嗯,确实,我买的域名也差不多是些乱七八糟的字母组合,但……” 不管怎样,这是我的一个小笑话。

Erik St. Martin: 我也讨厌别人试图卖给你……还有一件事是,如果你搜索了一个域名但没有立刻买下它,过一段时间你再去看,它总是变成了高价的“高级域名”。你会想,“真的吗?!” 所以你得在搜索的那一刻准备好买下,否则他们可能会抬价。

Brian Ketelsen: 这也是我的问题。

Brad Fitzpatrick: 如果你通过注册商的搜索表单来搜索,他们就会知道。你应该通过 Whois 直接查询,这样他们就不会知道你在搜索那个域名。

Erik St. Martin: 通过 Whois 搜索域名……[笑]

Carlisia Thompson: 是啊……用终端来搜索。

Brian Ketelsen: 我每次都带着信用卡去注册商那里。

Erik St. Martin: 你之前提到了 1.9 版本……你在 1.9 版本中具体负责哪些工作?能透露一些吗?

Brad Fitzpatrick: 其实我在尝试看看我能在 1.9 版本中尽量少动代码。我做的很多事情实际上是为了让社区更多地参与进来,帮助处理 bug triage(问题分类)和代码审查……因为随着 Go 在内部和外部的不断发展,我们收到的 bug 报告和提交的代码变得越来越多,只有我们几个在做代码审查,这种模式已经无法扩展了,因为我们花了大量时间在分类和审查上。

所以我正在尝试让社区更容易参与进来,这样他们不会感到害怕,他们知道流程,或者我们有更好的仪表盘告诉他们哪些事情需要注意……

我们创建了一个叫 Gardening 的 wiki 页面,这个页面列出了所有你可以做的“园艺”任务。如果你有五到十分钟的时间想为 Go 项目做点贡献,我们会列出一些 GitHub 查询,看看有哪些问题需要关注,或者最近有哪些代码审查,还有一些只需要花几分钟时间就能完成的任务,但这些任务可以推动项目向前发展。

Carlisia Thompson: 这个列表在哪里?

Brad Fitzpatrick: 在 golang.org/wiki/gardening 上。很多开源项目使用“园艺”这个词来形容一些后台的清理任务……就像园艺一样,拔草的工作永远做不完。上面列了很多任务。

比如我们在某个 bug 上加了“等待信息”的标签,你可以看看这些在 GitHub 上标记为“等待信息”的 bug,看看“这个 bug 应该关闭吗?是否超时了?提交人有没有反馈我们要求的信息?”就是推动这些 bug 向前发展,有必要时提醒一下。

如果有人提交了代码审查,但提交信息格式不对,你可以告诉他们如何格式化提交信息,提醒他们忘记加测试了,或者找到拼写错误……有很多简单的事情你可以做,这些与代码修正本身无关,但可以让代码审查过程更顺利。

Erik St. Martin: 这是个有趣的想法……通常在版本发布周期时,Dave Cheney 会做一个演讲,然后多个 Go 社区的 meetup 会使用这个演讲内容。

Brad Fitzpatrick: 是的,全球发布派对。

Erik St. Martin: 是的,我在想,是否可以做一个类似的共享演示文稿,这样各个 meetups 就可以用它作为内容?很多 meetups 总是寻找内容,每个人都可以做展示,或者把它变成“嘿,我们这个月没有什么话题,大家来开个园艺派对吧”,大家一起做一些问题分类的工作,每隔一个月做一次,这样它就变成了一种协作努力,大家可以互相指导那些从未参与过的人。

Brad Fitzpatrick: 这是个有趣的想法。也许我可以在西雅图的 meetup 上试试。

Carlisia Thompson: 这让我想起了很多语言社区都有的 Bugmash 活动,对吧?

Brian Ketelsen: Bugmash,没错。

Carlisia Thompson: 我们还没有类似的活动。Brad,你觉得组织一个怎么样?

Brad Fitzpatrick: 我不知道那是什么。

Carlisia Thompson: Bugmash 就是---Brian,你可以纠正我---安排几天时间,先由维护者列出需要解决的问题。然后我们号召大家在这几天内一起集中精力解决这些问题。

Brad Fitzpatrick: 哦,我明白了……就像一个 bug 燃尽活动,或者修复周,类似的东西。

Carlisia Thompson: 没错。每种语言、每个社区的名称不同。

Brian Ketelsen: 是的,重点是吸引那些之前可能没有参与过的人。所以,与其花五分钟自己修复一个小问题,你可以花二十分钟把它变得非常简单,让那些从未提交过补丁的人也能参与进来。

Carlisia Thompson: 完全正确。

Brad Fitzpatrick: 这实际上是我过去三个月以来一直在待办事项上的一件事。我上一季度应该做的一件事是写一篇博客,介绍如何为 Go 提供贡献以及如何参与这些事情,但我一直在推迟,因为我想要有更多的仪表板让人们使用,这样会让参与变得更容易……但总有一个时刻我需要告诉自己,够了,现在的状况已经足够好了,足够让人们参与进来。

Erik St. Martin: 是的,我认为这种争论也是正确的。我记得 Bugmash 或其他类似的活动---Ruby 也有一个,但我记得它不叫 Bugmash,叫别的什么……这类活动通常是为那些想贡献代码的人准备的,而很多人在刚开始时并不熟悉代码库以及它的工作方式,他们也没有足够的信心去贡献代码。所以我觉得你不会在这类活动中看到太多参与者,反而在“嘿,你可能不想直接贡献代码,但你可以用这些方式贡献”的活动中,会看到更多人参与。通过这样做,他们会熟悉这个项目和各个组件,进而可能通过这种方式建立起信心。

我在一些聚会中也看到过类似的情况,很多人需要很长时间才能鼓起勇气提交代码更改。他们总是担心会被批评……有时候确实会,但每个人的反应不同。我觉得帮助进行项目维护(gardening)是建立信心的一种方式,因为你会熟悉项目的贡献者,了解谁负责什么,应该问什么问题,票据(tickets)会经历哪些阶段,因为你已经习惯参与这个过程了。

Brad Fitzpatrick: 至少我们现在有一个专门给审查员的 Slack 频道……就是 GopherSlack 上的 reviews 频道,人们可以在那里聚集,处理问题并维护项目。

Brian Ketelsen: 我都不知道有这个频道。

Carlisia Thompson: 我也不知道……但我觉得任何社区努力,为了帮助人们聚在一起并提供一点支持,以克服设置环境的障碍,并让他们有动力进行设置,因为他们知道会有一份简单的任务清单,这对于初次参与的人来说非常重要。

举个例子,我从来没有为 Go 贡献过代码,但昨天我花了一点时间进行设置,我只想加一行文字,但我得先完成整个设置过程……不过,这个过程其实很简单。虽然花了一些时间,但并不难。

Brad Fitzpatrick: 我个人讨厌我们的贡献流程,还有那篇冗长的文档,吓跑了很多人……其实步骤并不多,但文字太多了,大家看到它就想跑掉,还会问“为什么你们不用 GitHub?”

答案是我们可能应该用……当我们迁移到 GitHub 时,其实是一个非常快速的、被迫的迁移,因为 code.google.com 要关闭了,所以 GitHub 是显而易见的选择,他们有问题跟踪器,但我们当时并不准备放弃 Gerrit,因为 GitHub 上的代码审查历史上一直不太好。虽然 GitHub 现在变得好多了,但我们真的很喜欢 Gerrit。所以我们说,“好吧,我们可以用 GitHub 作为问题跟踪器、wiki 等,但代码审查还是用 Gerrit,GitHub 只是一个镜像。”不过可能是时候写一些工具来接受 GitHub 上的 pull requests,至少目前可以自动转化为 Gerrit 更改,这样审查仍然在 Gerrit 上进行,Gerrit 仍然是上游……但如果有人只熟悉 GitHub 流程,他们可以继续在 GitHub 上发 PR,然后我们透明地更新 Gerrit CL。我们可能需要从这个开始,但……

Carlisia Thompson: 是的,就像我刚才说的,虽然设置过程不难,但确实花了一些时间,我有时会觉得很沮丧;我会读完一段文字,然后做一件事,然后去做别的事情……“啊!我不想读完这些内容!”所以我来回折腾,最后用了几个小时完成了所有步骤。但这只是你需要做一次的事情,如果你只是为了做一件小事而要经历整个过程,那真的很让人泄气。

现在我完成了这些步骤,我已经拉取了代码,把 Go 项目里的博客和网站都设好了……如果我想做一个文档更改,现在超级简单。我只需要同步一下,像平常一样开始一个分支,然后……虽然我不太懂术语,但用 Git 术语来说,我只需要推送。

现在我有了这些设置,真的很简单。我只需要找出,“好吧,我能根据现有需求做出哪些贡献?”这又回到了我之前说的,举办一些 Bugmash 活动,这会非常棒。

Brad Fitzpatrick: 是啊,既然你已经花了几个小时设置好了,现在你需要修复一堆 bug 来平摊那些时间成本。

Carlisia Thompson: 没错。 [笑] 我已经赚回了我的时间。

Erik St. Martin: 另一个人们可能不太熟悉的事情是,如果你在找任务的话,GitHub 上有一个 Help Wanted 标签。

Carlisia Thompson: 是的,我现在就在找。

Brad Fitzpatrick: 人们总是要求我们多用这个标签;他们想要更多的任务……但我其实不太喜欢这个标签,因为我们似乎从来没有很好地使用它。因为没有一个明确的定义说明它的含义是什么。大家想要一个像 EasyBeginner Friendly 这样的标签,但问题是,对于一个人来说简单的事情,对于另一个人来说可能完全不同。

如果某件事真的对所有人都很简单,它早就被修复了。我们从来不知道问题有多复杂,而 Help Wanted 这个标签也有点傻,因为我们希望每个 bug 都能被帮助修复。我最近越来越多地使用 Help Wanted,但我基本上把它加在所有问题上……这也没什么问题,但我觉得大家应该随意地跳进去并开始解决任何问题。

Erik St. Martin: 是的,我曾为一个项目贡献过代码,我记不清是哪一个了---可能是 Ruby,或者其他什么……他们的标签是 Bite-Sized,或者类似的东西,意思是你可以在一次会议里完成---至少大多数人可以---而不是那些更大规模的实现,比如 Generics。你可能会用 Help Wanted 标签,因为你希望得到别人的意见,但这显然不是新人可以在一小时内完成的贡献……

Brian Ketelsen: 我们需要一个 GenericsMash

Carlisia Thompson: 我想说一下关于 Beginner 标签的事情……当我刚开始学习 Go 时,我有一次经历,我去一个开源项目,他们有一个标签是给初学者的(或者叫 Easy 或类似的标签),我看着这些问题,心想“天哪!这也太难了。如果这是初学者级别的……哇,那中级是什么?简直是火箭科学。”所以这真的把我吓跑了,但我已经编程有一段时间了,所以我学了一段时间后还是给了自己一个机会,现在我能理解这些东西了。

但就像 Brad 说的,如果你给某个东西贴上初学者标签,对于你来说可能很简单的事情,对于新手来说可能非常复杂。你可能真的会吓到别人。你必须小心那些标签,但我喜欢根据任务大小或时间片段来做标签……这很不错。

Brad Fitzpatrick: 嗯,很多时候你在实际做之前并不知道它有多复杂。

Carlisia Thompson: 这也是一个问题。

Erik St. Martin: 我觉得我们已经超时了,该进行我们的第一个赞助商广告了……咱们先休息一下。今天的第一个赞助商是 Toptal。

Erik St. Martin: 好的,我们回来了,继续和 Brad Fitzpatrick 聊天。我们在广告前谈论了 Go 和贡献的问题,但我想继续问的是,你总是有一些很酷的业余项目在进行……你现在在做什么有趣的事情?

Brad Fitzpatrick: 嗯,我最近搬到了西雅图,所以我一直在做一些杂七杂八的家庭自动化项目。我们装了不少 Z-wave 灯光开关,我还买了一些便宜的安全摄像头,现在我正在自己做运动检测系统……

其实,我在上次 GopherCon 上做了一个关于我的运动检测安全系统的闪电演讲。每当我有一点空闲时间,我就会尝试改进这个系统。

Erik St. Martin: 你是用 Go 做的吗,还是你用的是 OpenCV

Brad Fitzpatrick: 不,几乎都是用 Go。我在家里有一个小型的 Go 服务器,它连接到摄像头,获取压缩的 MPEG 视频流,然后我把它流传输到一个云实例上,那里有更多的计算能力。然后我让一个小的 FFMPEG 子进程来解码视频,并且它还使用 FFMPEG 内置的边缘(EDGE)检测功能。然后我直接通过 FFMPEG 的标准输出输出原始像素,我从 FFMPEG 中读取具有边缘检测的原始像素,并计算随着时间变化的边缘移动位置,一旦它跨越了某些阈值并进入视频的某些区域,我就开始记录。

即使没有任何运动,我也会一直记录最近 5 到 6 秒的内容,存放在一个循环缓冲区中,但一旦有运动,我就会把它流传输到云存储中。

我在后台还有一些小进程会从中生成 GIF,挑选出最有趣的帧,生成两秒钟的小 GIF。然后我可以通过 Telegram 或其他途径发送这些 GIF。这挺有趣的。

Erik St. Martin: 你把所有的原始视频流传输到云端……你的 ISP 一定很“爱”你。

Brad Fitzpatrick: 我有千兆宽带,没问题……

Erik St. Martin: 太棒了。说到超出人们能力范围的项目---我不确定我能不能构建一个像你这样能处理所有边缘检测的系统……这真是太棒了。你还需要为那些 GIF 添加随机的标题……

Brad Fitzpatrick: 是的,我也在想通过 Google Vision API,识别出物体……有一次我的运动检测系统捕捉到了一些猫,它们在我的前廊上玩耍。那是一只黑猫和一只灰猫,它们互相追逐……

Brian Ketelsen: 那会很酷!这样你就可以收到一条短信说“你家后院有猫。”

Brad Fitzpatrick: 猫咪警报。

Brian Ketelsen: 我喜欢这个主意。

Erik St. Martin: 还有你一直拍的那些天际线照片……你在做什么项目吗,还是只是定时拍摄并存储它们?

Brad Fitzpatrick: 当我刚搬进来的时候,我想对这里做点什么。西雅图有很多起重机,我想制作一段这些新摩天大楼拔地而起的延时摄影……所以我把一台相机装在屋顶上,每分钟拍一张照片并上传到云存储。现在我已经有大约 780,000 张 8 兆像素的 JPEG 照片了,所以我想用它们做点什么。我一直在想一些有趣的点子,比如做个小的网页应用,让你能拖动鼠标,太阳会跟着鼠标移动,或者追踪飞机或船只,或者按色调排序,这样你可以看到不同颜色的天空……但我还没花时间搞这些。我已经有了数据,这部分是最麻烦的,现在有了数据,我需要做点有趣的事情。

Erik St. Martin: 你在云提供商工作真是太好了,因为我觉得没有人会愿意承担你可能产生的账单……[笑]

Brad Fitzpatrick: 其实并不多。我想大概只有 150 GB 左右。

Brian Ketelsen: 这还行。

Brad Fitzpatrick: 是啊,这不算多。

Brian Ketelsen: 这只是我 iTunes 库的一半。 [笑声]

Brad Fitzpatrick: 你还在收集音乐吗?

Brian Ketelsen: 我收集了很长一段时间,但现在我甚至不再用 iTunes 了。

Brad Fitzpatrick: 我刚卖掉了我的车,找到了我以前的 iPod……那种带旋转硬盘的大 iPod,它还一直在我的手套箱里,连接着车,因为车里有一根 iPod 连接线……这基本上是我大学时期的音乐收藏,存在这块 80GB 的硬盘里,虽然从那以后就没更新过,但它还在工作。

Brian Ketelsen: 这太酷了……我昨天在抽屉里找到了一张索尼 MiniDisc,但我完全不知道上面有什么音乐。我确定它一定很精彩,但我完全没法知道上面是什么。

Erik St. Martin: 我确定你可以在 Craigslist 上找到配套的驱动器……应该有人有一个…… (译者注: 类似国内的58同城)

Brian Ketelsen: 是啊,如果我在意的话……

Erik St. Martin: 我可能也有一两个便携硬盘里存着音乐,但我一直保存着它,因为我想,“万一我真的需要这些 MP3 呢?”

Brian Ketelsen: 你的 Napster 收藏?

Erik St. Martin: 现在太方便了……你可以从任何设备上流媒体播放;我的车里有蓝牙连接,Spotify 直接播放---问题解决了。我不需要 MP3 了。

Brad Fitzpatrick: 我找到了一箱我最早写的 Apple 2 程序,存放在这些五又四分之一英寸的软盘上,但我没法读它们。后来有人在网上说:“哦,我有读取这些的硬件。我可以帮你制作镜像并把原始数据发给你。”然后我想我可以把它放到模拟器里,或者干点别的。所以我把软盘寄给他了,但从那以后我再也没有听到他的消息。我每隔六个月发一次邮件问他:“嘿,你还留着这些盘吗?能寄回来吗?”但没有任何回复……

Erik St. Martin: 哎呀。

Brian Ketelsen: 哎呀……

Brad Fitzpatrick: 不过没关系,它们可能已经坏了。

Erik St. Martin: 或者,你最近有没有身份被盗? [笑声] 也许他发现了什么好东西,然后想:“哦……”

Brad Fitzpatrick: 不,那些程序---它们一点也不好。

Erik St. Martin: 我还是很怀念那些日子……我总是问那些有五又四分之一英寸软盘的人:“你有《俄勒冈之旅》吗?” 我打赌你现在可以在模拟器里玩到它了……

Brian Ketelsen: 你们真年轻……当我还是个孩子时,我们必须从 Byte 杂志的背面手动输入应用程序,而且一旦关机,程序就没了。

Erik St. Martin: 每次你想用它都得重新输入一遍吗?

Brian Ketelsen: 对的。我刚开始学计算机时,甚至没有磁带机来保存程序。

Erik St. Martin: 那绝对比我的时代要早。

Brian Ketelsen: 我妈会进来说:“你得把那玩意关了。” 我说:“不,不,不……我们不能关机。” 不,不,不……那可是很多的输入啊。

Erik St. Martin: 我记得有 28k 的调制解调器。如果你想要音乐,想要整张 CD,你得开一晚上,还得祈祷没人断开电话线……早上醒来时,“不---!”

现在想想挺有趣的,现在的年轻一代可能都不明白这其中的讽刺。我们很多人刚开始用互联网的时候,得拨号上网,对吧?互联网是通过电话线提供的,但现在电话却是通过互联网线提供的。

Brad Fitzpatrick: 你们看过电视剧《Halt and Catch Fire》吗?

Brian Ketelsen: 没有。

Erik St. Martin: 只看了几集。

Brad Fitzpatrick: 好的……这部剧讲述了 70 年代末和 80 年代的计算机行业,我记得第二季讲的是一家拨号 ISP,类似于一个 BBS 系统公司,他们正在建立这个公司。整部剧充满了怀旧感……这是很不错的一部电视剧。

Carlisia Thompson: 那是部好剧。我也没看完所有剧集,但我需要补完。谢谢你提醒我。

Erik St. Martin: HBO 有一部关于创业生活的剧叫什么来着?

Brian Ketelsen: 《硅谷》?

Erik St. Martin: 对,就是那部,还有另一部。我想《硅谷》就是那部。那部剧太搞笑了……

Carlisia Thompson: 太搞笑了。

Brian Ketelsen: 我看不下去……感觉太真实了。

Erik St. Martin: 就像,“嗯,有个人拿了钱,然后我想他自杀了。” 结果是,“不,等等……也许他没拿钱。哦,我记不清了。” [笑声]

Carlisia Thompson: 我觉得他们做得很好,他们在咨询方面做得不错,不论他们咨询了谁。

Brian Ketelsen: 可能是 Brad。

Erik St. Martin: 背后是 Brad。

Brian Ketelsen: 对。

Carlisia Thompson: 可能是。我们刚才在聊存储,当然我们得聊聊---我不知道该怎么念……Camlistore

Brad Fitzpatrick: 对……那个临时名字,结果并不临时。我一直以为有一天我会给它改名。

Carlisia Thompson: 是啊……我看了你的视频,知道这是个缩写。

Brad Fitzpatrick: 是的,这是让我进入 Go 语言的项目。当时我在 Google 的山景城工作,做 Android 项目,我每天从旧金山到山景城的通勤,顺利的话要 45 分钟,不顺利的话要两个小时。

所以有时候我得在车上消磨四个小时,我要么恨自己的生活,要么就写点代码……但我需要写点什么东西,于是我有了这个想法,我想构建一个终极存储系统,用来备份所有我的东西,归档我所有的社交网络内容。我有些推文在这儿,照片在那儿,博客文章又在别的地方……我想把我所有的东西---所有备份、文件和内容---全都集中在一个系统里。我还想用这个系统托管我所有的网站。

我知道自己想要的数据模型,我也知道想要的协议;我做了很多笔记……然后我只需要实际构建这个东西,并且选择一门编程语言。我在 Google 搜索了几种选择:C++、Python 或 Java……我在这些语言上都有很多经验,知道我肯定不想再用它们……

C++ 基本上只有在你有像 Google 那样庞大的标准库和优秀的构建系统时才可用,否则 C++ 的工具链很痛苦。我写了很多 Python 和 Perl,知道它们并不适合写服务器,因为你要么得做很多回调之类的事情,要么性能非常差……当时我写 Java 做 Android,Java 我也写够了,已经厌倦了。

就在这个时候,Go 语言刚好问世,所以我决定用 Go 语言先做个原型。我在通勤的公交车上开始搞这个,真是太棒了,因为我不需要网络,当时的工具已经足够好了……那时候还没有 go 命令,你得用 Makefile,但编译速度非常快,所以还不算太糟糕……我不断发现标准库里缺少一些东西,HTTP 包也有些问题,所以我就开始给 Go 团队提交修改,当时 Go 团队成员基本上是 Russ、Ian 和 Robert。Russ 不断批准我提交的 HTTP 修改,我就不断提交更多的代码,最终我全职转到 Go 团队。

有一天我收到 Rob 的邮件,他问我:“嘿,你想全职做这个吗?” 当时我已经在 Android 团队工作了几年,显然 Android 已经站稳脚跟了……它不再是个疯狂的想法了,所以是时候去做一些新的疯狂想法了。但现在看来,Go 语言可能也要站稳脚跟了……

Carlisia Thompson: 那现在是不是该换个方向了……

Brad Fitzpatrick: 我不知道……我不知道我还能做什么。

Brian Ketelsen: 我记得非常清楚……大概是在2010年中期,有一段时间,Go语言的每一个改动几乎都由Camlistore的变化驱动。可以说,就像钟表一样精确。

Brad Fitzpatrick: 是的,很多HTTP方面的东西源自那里,数据库部分也是,还有很多字符串包的改动……甚至像strings.Contains()这样非常基础的功能。

Carlisia Thompson: 我看了你的视频介绍了Camlistore,觉得真的很酷。有听众ZelenHunter提了一些关于Camlistore的问题,他问:“你会回到积极开发Camlistore的状态吗?”我看到你确实在本月发布了一个版本,但这是否意味着你重新开始积极投入开发了?

Brad Fitzpatrick: 不,我现在主要是审查另一个开发人员Mathieu的工作。他一直在持续开发。我仍然在观察并参与其中,但不像以前那样写很多代码了。也许等我休产假时,我会在休息时继续开发。我们拭目以待吧。

Carlisia Thompson: 你觉得它未来会成为一个成熟的产品吗?

Brad Fitzpatrick: 其实它现在已经相当可用和稳定了。每次发布新版本,它都会变得更主流、更易用。我记得两三次发布前,我们做了一个启动器……如果你访问Camlistore.org/launch,我们有一个表单,可以帮助你在Google Cloud上创建自己的实例。

Brian Ketelsen: 这很酷。

Carlisia Thompson: 确实很酷。

Brad Fitzpatrick: 当时出来的时候,虽然运行了,但使用的是一个丑陋的IP地址,安全性依赖于自签名的HTTPS证书。后来我去开发了Let’s Encrypt支持,并将其添加到Golang中。我和另一个人合作,他实现了Acme协议,然后我做了一个Autocert包,也就是Golang x/crypto/acme/autocert……我们也把这个加入了Camlistore。

现在Camlistore可以获取Let’s Encrypt的证书了,但我们还需要自动生成域名,这样当用户创建自己的实例时,他们就可以直接使用。于是我们创建了一个DNS服务器,用户可以自动获得Camlistore.net的子域名。我们开发了一种类似Acme的协议,只要你能证明你拥有密钥对,就可以获得一个子域名。这个域名会有点丑,比如是你密钥的指纹.camlistore.net,而我们会自动设置DNS服务器关联,然后你可以为这个域名请求Let’s Encrypt证书。

最终的结果是,你通过这个向导,点击create vm,大约40到60秒后,你就能得到一个运行中的实例,带有完全信任的证书和域名。

Brian Ketelsen: 你们如何绕过Let’s Encrypt的子域名速率限制?因为他们的限制是每周20个子域名。

Brad Fitzpatrick: 我们的用户还不多,所以目前还没有遇到这个问题。

Brian Ketelsen: 好吧,不过要小心……这个问题迟早会来的。

Erik St. Martin: 接受挑战。

Brad Fitzpatrick: 是啊……如果真遇到这个问题,我们会帮助用户自己带域名,或者引导他们通过其他域名创建流程。

Carlisia Thompson: 另一个听众的问题是:“Go核心团队是如何应对倦怠的?”我并没有听说Go团队有倦怠问题,但我觉得这是个不错的问题,能谈谈这个吗?

Brad Fitzpatrick: 是的,确实有些重复的感觉。我知道Andrew去做Upspin项目了,因为他需要一些改变……你知道,当你多年做着同样的事时,确实会有些单调。

我自己也有点这种感觉,因为我想Go 1.9将是我参与的第10或第11个Go版本发布,还不算其中的所有小版本发布……有时候你会感到有些沮丧,因为有些东西你无法修复,而且你总是看到相同的bug报告和提案,不得不一遍遍地重复关闭这些bug,告诉大家“抱歉,我们不能更改这个”,或者“这要等到某种Go 2版本才能解决”……

我会尝试偶尔换一些不同的任务来做,专注于不同的事情……比如为Go 1.6开发的HTTP/2功能就是一个很好的分散注意力的项目,因为我可以实际编写代码,思考新的问题类型。现在,我在做关于社区互动的统计和仪表盘,这在某些方面也很有趣……我还专注于Kubernetes,定义我们的构建基础设施和运行Go构建系统的所有微服务……学习Kubernetes的过程中,我确实感到了一些乐趣。不过,确实有时候事情会变得非常重复和无聊,然后我就得找一些新东西来做一段时间。

Erik St. Martin: 你觉得不能做出改变的挫败感,可能会激励大家推动2.0的开发,或者至少开始思考和讨论2.0可能是什么样子吗?

Brad Fitzpatrick: 是的,我觉得我们大家都有这种感觉,觉得我们可能需要做一个Go 2。我不确定,但Go成为一个开源项目已经接近十年了。Rob曾经说过,如果他要做Go 2,十年可能是一个合适的时间点。

就我个人而言,我最大的担忧是有另一个语言会出现,并且拥有像goroutines那样的功能。我觉得goroutines是Go的真正特色。没有其他语言能像Go那样很好地实现轻量级线程。其他语言可能已经借鉴了Go的优秀工具链,但Go的类型系统也非常有趣。如果有一门语言出现,具备非常好的工具链,同时依然简单且拥有goroutines,并且让编写服务器变得非常简单,但又有一个更强大的类型系统……

Brian Ketelsen: 你们看过Crystal语言吗?

Brad Fitzpatrick: 哪个?

Brian Ketelsen: Crystal是一种类似Ruby的语言,是用C或C++写的,速度非常快,编译成原生代码……它几乎复制了Go的goroutines和channels,功能齐全,而且速度真的非常快。标准库还需要一些完善,它还没有到1.0版本。我大概在一两个周末前玩了一下,确实像Ruby一样,但速度快得惊人。它会是一个有趣的存在……

Erik St. Martin: 我总是喜欢尝试新语言。

Brad Fitzpatrick: 谁在开发它?

Brian Ketelsen: 我不记得了……好像是欧洲的一个小团队。

Erik St. Martin: 那是crystal-lang.org

Brian Ketelsen: 它由Manas.tech赞助。

Brad Fitzpatrick: 有一家公司的支持,这很有希望,不是只有一个人在做。

Erik St. Martin: 尝试其他语言总是有趣的……Brian,我们这些年一起尝试过的其他语言有哪些?Pony, Nim……

Brian Ketelsen: Pony不适合我。Nim挺好玩的……还有哪些?我玩过Elixir……但Elixir对我来说变化不够大。

Erik St. Martin: 是的,你说得对---goroutines真的非常棒。我记得第一次发现你可以随意使用它们时的感觉……当你推荐给别人时,他们会问:“我可以有多少个?”“你需要多少就有多少。”“等等,没有上限吗?”“没有,继续使用goroutines吧。”

Brian Ketelsen: “你想要多少?”

Brad Fitzpatrick: 我一直在关注Rust和Swift……他们都在考虑添加轻量级任务或goroutines或fibers,或者你想叫它们什么都行,但这两个项目最终都放弃了,认为“这有点难,pthread可能已经够用了……也许我们以后再考虑。”

每个人都在思考这个问题,但没有人付诸实践。我相信最终会有人做到的。

Erik St. Martin: 哦,是的,我觉得肯定会有人做到,这只是个时间问题,是新语言做到,还是现有语言的新版本采用……但我认为很难不去考虑它,尤其是看到Go在短短几年内的快速增长。

我认为其他有前途的新语言至少得思考,为什么人们如此喜欢Go,并开始采用其中的一些特性。

Brian Ketelsen: 回到Crystal……Crystal确实有成功的配方,因为很多人喜欢Ruby的语法,而将goroutines和channels加入其中似乎是个不错的配方。但当你真正使用它时,它并不像Go那样顺畅。

Erik St. Martin: 听起来不够流畅,是吗?

Brian Ketelsen: 是的,我听过很多次……Go的核心优势之一是它的代码是为阅读而写的,而大多数语言不是。Go优化了代码的可读性,这对你的生产力有着巨大的影响……很难描述,要在其他地方复制这一点有多难。

Erik St. Martin: 我认为从另一个角度看,人们可能不愿意尝试Go,因为他们想要一种感觉复杂的语言……那种“哦,我需要学习一些超级酷且复杂的东西”的感觉,而不是他们认为更简单的语言。所以很难打破这个障碍,让他们意识到,“不论你的技能水平如何,你都会喜欢它。我保证。”

Brad Fitzpatrick: 你们知道YouTube正在开发一个用Go编写的Python运行时吗?我想叫Grumpy……

Brian Ketelsen: 哦,知道。

Erik St. Martin: 是的,是的。

Brad Fitzpatrick: 看看他们能走多远会很有趣。也很有趣的是,是否会有其他语言使用Go作为它们的运行时。

Erik St. Martin: 是的,上周我们还讨论了一个项目,看到有人正在用Go实现Ruby运行时。我不确定它已经进展到什么程度,但我们确实看到了。

Brian Ketelsen: 那不是有两个吗?两个不同的用Go实现的Ruby运行时?

Erik St. Martin: 其中一个是用Go实现的类似Ruby的语言,另一个是要符合Ruby规范的运行时。

Carlisia Thompson: 现在我们在聊语言,但我迫不及待地想问一个问题,其他人也在问……Go 语言是否有可能支持 泛型?如果答案是肯定的,那这个前景如何?我之所以问这个问题,是因为显然很多人都想知道,人们总是问这个问题,而且据我了解,这个问题从来没有被明确否定过。我觉得这个可能性的大门一直是敞开的。

Brad Fitzpatrick: 是的,我认为基本上每个人都希望引入泛型;团队中几乎没有什么反对泛型的声音。我认为如果我们能够在标准库中引入一些算法,并且能够在标准库或者某个共享库中加入更多的容器和数据结构,那会很棒,即使这些东西不直接在标准库中实现。但目前还没有一个很好的提案……

Ian Lance Taylor 目前已经写了五六个提案了,每次他基本上都会否决自己的提案。他甚至实现了其中几个……所以他可能是最终解决这个问题的人。我不知道他需要写到第七个还是第八个提案……[笑声] 但我觉得他离成功越来越近了。他似乎每次都更喜欢自己新写的提案一点点。

Carlisia Thompson: 你说的是哪位 Ian?

Brad Fitzpatrick: Ian Lance Taylor。他是 golang 项目的 Ent@,在 GitHub 上就是 Ian Lance Taylor。

Brian Ketelsen: 他主要负责 Go 的 GCC 移植。

Erik St. Martin: 对。

Brad Fitzpatrick: 是的,他还写了 gold 链接器。他对信号、链接器以及这些复杂的东西了如指掌,而这些是我不了解的。

Brian Ketelsen: 那些我想忽略的神奇内容。

Brad Fitzpatrick: 对……每当遇到一些非常奇怪的 UNIX 问题,比如“这是一个带有 TTY 会话领导的进程控制组,它接收到信号然后某些东西挂掉了,等等等等……”他就会说,“当然了……在 UNIX 中,这一页规范是这样写的,除了某个特定版本的 UNIX,等等……”他非常了解 UNIX 的工作原理以及底层的东西,而且他也经常思考编程语言的问题……

总的来说,我觉得如果有 Go 2,它应该会有 泛型。我不认为我们会发布一个没有 泛型 的 Go 2;那样的话它就不够有吸引力了。如果要进行 Go 2 这样大的变动而不加入泛型,那就不值得。我想 Go 2 可能会在某个时刻出现,只是不确定具体时间。

Erik St. Martin: 是的,我也不认为你会告诉大家“泛型会在 Go 3 中实现”,当他们看到 Go 2 花了多长时间才推出时,他们就会知道这永远不会发生了。

Brad Fitzpatrick: 我还认为如果有 Go 2,我们不能像 Python 3 或 Perl 6 那样彻底“炸毁”整个世界,然后期待一切都会好起来。

Erik St. Martin: 哦,是的……

Brad Fitzpatrick: 我认为……我没有仔细考虑过细节,但我觉得如果在 Go 2 中,你可以导入 Go 1 的包并使用它,但是 Go 1 的包不能导入 Go 2 的包,因为两者的语义会有所不同。我认为我们必须在某种程度上让这两个生态系统共存。

Erik St. Martin: 这很有趣。我觉得我们错过了第二次赞助商广告的时间,所以我们还是先插播一下。今天的第二位赞助商是 DataDog。

Erik St. Martin: 好了,我们回来了,继续和 Brad Fitzpatrick 聊天。我们刚刚谈到了对于 Go 2 的愿景。有没有人想聊聊过去一周看到的一些有趣的项目或新闻?我看到一个很有意思的……

Brian Ketelsen: 我也有一个很棒的……实际上,我有三个好东西。

Erik St. Martin: 你有三个?

Brian Ketelsen: 我有三个好东西,所以你先说吧。

Erik St. Martin: 你是不是把好东西都占了?

Brian Ketelsen: 没有。

Erik St. Martin: 希望我不会把名字读错,我看到了一个叫 periph.io 的项目,是 Marc-Antoine Ruel 做的。它是 Gobot 的一个替代品,不需要任何支持库或者 CGO。我和他聊了一会儿,了解到它可以在 MHz 范围内进行位操作。我们其实已经安排了他两周后上节目,届时会有更多细节……但这个项目对做 GPIO、I2C 和 SPI 的人来说真的很棒……它也刚刚实现了单线协议,所以如果你在玩 BeagleBone 或者 Raspberry Pi,并且做 GPIO 相关的项目,这是一个很值得一试的项目。

Brian Ketelsen: 太棒了……可以用来做烧烤了。 [笑声]

Erik St. Martin: 我知道……很尴尬,因为我决定在做探针和其他东西时只用 ARM 处理器,直接用嵌入式 C,然后我看到了这个项目,我就有点想重新用单板计算机了。

Brian Ketelsen: 改变主意是可以的……绝对没问题。

Erik St. Martin: 是的。

Brian Ketelsen: 我有一个很酷的项目和一个致敬要提一下……我们的一位听众在徒步穿越阿尔卑斯山时听我们的 GoTime 播客,上周他给我们发了一封邮件,介绍了他的代码生成工具,因为他知道我有多喜欢代码生成……

这个代码生成工具在 github.com/dave/jennifer 上。不幸的是,广播不能传达图片……不过,我们会试着找个办法发出 Dave 在阿尔卑斯山顶上拍的照片,照片里他对着我们挥手致意,因为他在听 GoTime。所以,致敬你,Dave……太棒了。我想 GoTime 大概是徒步那些无聊的阿尔卑斯山时最好的伴侣。

Carlisia Thompson: Dave 有姓吗?

Brian Ketelsen: 我不知道 Dave 的姓。我得翻一下邮件看看。

Erik St. Martin: 在爬完一座山后听到 “It is GoTime” 的播报会是什么感觉?

Brian Ketelsen: [笑声] 像天堂的声音。它听起来像天堂。所以这是一个。另一个很棒的公告来自 github.com/myitcv/react,这是为 GopherJS 提供的 React 绑定。现在它还支持 Preact,这很棒,因为 Preact 比 React 小得多……所以我很期待有点空闲时间来玩一下 GopherJS 的 React 绑定。

这些绑定特别酷(它们是 Paul Jolly 做的),因为它们为所有繁琐的部分做了代码生成。所以你只需实现几个接口,然后运行 go generate,它就会生成所有的 Go 代码,这些代码会被编译成 GopherJS 代码,进而与 React 或 Preact 交互。

Erik St. Martin: Brad,你也在做一些 GopherJS 的东西,对吧?

Brad Fitzpatrick: 不太多……Mathieu 正在将我们一些 Camlistore 的东西过渡到 GopherJS,并且开始使用 React,我看了看,觉得有点道理,但我自己用得不多。

Erik St. Martin: 我觉得 React 让我爱上了用 Go 来做 Web 应用。在这之前,像用 Rails 做前端那样会让我觉得“哦,做前端好难……”,但 React 实在是太容易让人搭建一个 UI 了,尤其是基于 Go 的 API。

Carlisia Thompson: 所以 Dave 的姓是 Brophy。

Brian Ketelsen: 哦,谢谢你。Dave Brophy,对的。

Carlisia Thompson: 别感谢我,感谢 Florin Patan

Brian Ketelsen: 哦,干得好,Florin!这就是为什么我们在 GopherSlack 里有一群听众来帮我们解围。

Erik St. Martin: 是啊,为什么我们是主持人?他们似乎比我们知道得还多。

Brian Ketelsen: 我知道,挺搞笑的,不是吗?

Carlisia Thompson: 他们确实比我们懂得多。我们只是随意发挥,他们做了所有的工作。

Erik St. Martin: Brian,是你问的“Go 2 真的会发生吗?”这个问题吗?

Brian Ketelsen: 不,那不是我。

Carlisia Thompson: 是我。

Brian Ketelsen: 是从 Reddit 上的吗?

Carlisia Thompson: 是的。Reddit 上有一个标题是 Go 2 真的会发生吗?如果是,那什么时候开始开发?。这个帖子非常长。

Erik St. Martin: 有趣的是,我们刚刚谈到了这一点,谈到了它可能需要包含什么,以及大概的时间线……你刚刚说十年左右的时间点可能是对的,但听起来在那之前会有关于它应该是什么样子的讨论,以及提案之类的事情。

Brad Fitzpatrick: 我给你们一个有趣的思考题……如果你们做了 Go 2,并且我们从标准库中移除一些东西,你们会移除什么,或者说你们觉得可以移除多少?

Erik St. Martin: 哦,有意思。我觉得可能有很多东西可以移除……大概 30% 左右,基于我编写的代码以及我使用的组件之少。但这也很难说,因为有多少人使用我不用的那些组件呢……?

Brad Fitzpatrick: 你需要一个糟糕的 SMTP 客户端实现吗?

Brian Ketelsen: 不需要。

Erik St. Martin: 不需要。

Brad Fitzpatrick: 你需要 X509 吗?

Brian Ketelsen: 不需要……我们不需要 Archive,不需要 Compress,也不需要 Container。

Carlisia Thompson: 我其实用过 X509。

Brian Ketelsen: 但它们不需要在标准库里……它们依然可以放在别的地方。

Carlisia Thompson: 对。

Brian Ketelsen: 我认为标准库的门槛应该更高,可能可以去掉 80% 的内容,而不是 30%。

Brad Fitzpatrick: 那么,这里有个更疯狂的问题---你能去掉 HTTP 吗?

Brian Ketelsen: 是的,绝对可以。

Brad Fitzpatrick: 但这也是人们意见不同的地方。很多人认为内置 HTTP 是很有趣的,但我觉得它有点维护起来麻烦。

Erik St. Martin: 是的,这就是两难的地方,对吧?因为标准库中的 HTTP 确实有优势,比如我记得刚开始使用 Go 时,做 HTTP 的工作非常容易,因为我不用去找一个库,或者写一个库,也不用纠结用哪一个是社区公认的标准库。然而,标准库中包含的内容越多,就越要符合 Go 1 的保证对吧?这意味着它不能轻易更改。所以将它移出标准库可以让它的发展速度更快。

Brad Fitzpatrick: 是啊。标准库中最有趣的事情是,你可以围绕某些类型构建整个生态系统。每个人都使用 time.timetime.duration,或者 context.now,对吧?而不是说“你使用哪个 context 包?”或者“你使用哪个时间包?”

这也是我们最初将 DatabaseSQL 添加到标准库中的原因之一,因为我们看到 GitHub 上有四五个数据库包,它们的接口完全不同,比如 MySQL、SQLite 以及一些 Postgres… 所以我们将它添加到了 Go 1 中,以便统一整个生态系统,使其感觉一致。但我不知道… 最小的标准库该是什么样的呢?

Carlisia Thompson: 我认为在回答这个问题时,你还需要考虑可用性,甚至有位听众 Chris Benson 提到过关于市场推广的事情,HTTP 在标准库中的存在有助于 Go 的推广。在看到他提到这个之前,我就已经在想这件事了。Go 的一个最大亮点是,“看,这是一门非常出色的服务器端语言!它甚至在标准库中就有 HTTP。用 Go 启动一个服务器非常容易!” 所以,即使维护它可能会有些麻烦,但你必须权衡它在吸引用户和提高可用性方面的作用。

Erik St. Martin: 是的,我觉得你提到了可用性问题,但我认为大家还是会有共识的… 比如说在 Ruby 社区---有很多常用的包,社区公认那些包是大家都会使用的,虽然它们并不是标准库的一部分。我觉得有些像 time 和 context 这样的核心类型是必要的,因为它们可能会被共享使用。但至于你如何使用它们,比如 HTTP,任何抽象网络栈、系统调用的东西,Matt Layer 在 GoTime FM 频道中也提到了这些。

这些东西是我认为必要的,尤其是为了提高语言的采用率。很多人---你也提到了,Brad---并不熟悉 Linux 的底层机制,以及信号处理、系统调用和其他功能。将这些东西抽象出来,的确有助于提高语言的采用率。

Brian Ketelsen: 我们需要记住的是,回到我最早学习 Java 的时候,你需要选择一个 Java 框架,基本上就是选择你的标准库。是 Apache Commons 还是 Java X?如果我们从 Go 的标准库中移除太多内容,我们可能会通过迫使大家选择不同的包,来导致社区的分裂,这可能会很奇怪。

Erik St. Martin: 不过,现在有很多有趣的工具可以帮助我们找到包和工具,例如---我们经常讨论的那个 Chrome 插件…

Brian Ketelsen: Sourcegraph

Erik St. Martin: 没错,Sourcegraph。它是一个非常有趣的工具,可以帮助我们找到包,看它们是如何使用的,以及有多少人使用它们。所以,问题真的在于这些东西必须在标准库中吗,还是我们需要更好的方式来找到这些东西?

我觉得困难在于维护,对吧?如果它在标准库中---这有点像反方观点的论据---我们可以保证它的维护。我记得早期有几个 MySQL 驱动程序被弃用了,你会想“好吧,现在哪个是最流行的?我们该迁移到哪个?”

Carlisia Thompson: 我觉得找到库可能不是最大的难题。你可能能找到东西,但接下来你需要决定用哪个库,你又该用什么标准来评判呢?我不知道… 回到 HTTP 的例子,我不能数清楚我见过多少次人们问“我应该用哪个框架?”而有经验的开发者会说“只用标准库就行,它很简单。即使你需要多写一些代码来获取参数值,也只用标准库”,然后人们会说“好吧… 即使有很多 HTTP 框架。”

Erik St. Martin: 那 Go 团队对于推广标准库之外的其他库的立场是什么呢?比如说,作为一种思想实验,如果这些标准库不存在,人们可能会期待 Go 团队指引他们使用某些库。Go 团队对此是什么态度?如果有一个更好的 HTTP 库,Go 团队会引导大家使用吗?还是你们尽量避免参与其他人的项目推广?

Brad Fitzpatrick: 其实,我们没有一个明确的政策来支持或反对。大多数情况下,我们不参与,因为我们没有时间在社区中做无偿的代码审查。我们曾经推广---现在还在推广---miekg DNS 库。每当有人有一些比较复杂的 DNS 需求时,我们会说“这里有一个非常完善的 DNS 包,它可以满足你所有的需求。” 所以,是的,当有明确的解决方案时,我们会推荐给大家。

Erik St. Martin: 只要有资深开发者引导大家使用这些库,我觉得就没什么问题… 我有时候想过,可能会通宵去浏览一下,列出我觉得没用的库。

能做一个社区调查,看看大家的共识是什么,也挺有趣的。

Brad Fitzpatrick: 我觉得你不需要做调查。你可以查看 GitHub 上的代码库,对吧?你可以看看它们的导入包。我们在 GoDoc.org 上有这些数据,只是我们没好好利用。

Erik St. Martin: 这也是个好主意,没错。

Brian Ketelsen: 我觉得我们应该把所有的包放到一个岛上,让它们决斗,看看哪个能留下来。 [笑声]

Erik St. Martin: 打破一根扫帚…

Brian Ketelsen: 如果你没有实力,你就不能留下。

Erik St. Martin: 也许有趣的是,看看有多少包几乎没人用,或者用得很少。但这很难判断… 当你想用机器学习去分析这些数据时,要怎么训练呢?可能像 HTTP 这样的东西,天生就因为我们写的软件类型而被更多使用。

Brad Fitzpatrick: 我最近发现,很多人都在使用我写的一个包,我感到很震惊---我写了一个 memcache 客户端,这是我用 Go 写的第一个包之一。当时我只是为了练习写包,实际上我自己几乎从未使用过它,但我写了很多测试,我启动了一个真正的 memcache 服务器作为子进程来测试它。然而,它的性能并不好… 它没有在连接上进行请求的流水线处理,所以如果你有很多活动在运行,你会发现所有这些新的 TCP 连接都指向你的 memcache 服务器,等等。 (译者注: 疑似这个是不是被DDOS攻击了…)

最近有一个 Google 云客户,还有一些其他的 Google 工程师开始调试这个库,并向我提交错误报告,说这个我几乎从未使用过的代码效率低下,我想“糟糕,现在我得维护这个东西了。”

Brian Ketelsen: 删除它。

Brad Fitzpatrick: 但是… 你知道的,我们的包管理工具几乎不存在或者很差劲,所以如果我删除它,我会破坏很多人的代码,这反而会带来更多问题。

Brian Ketelsen: 就像 left-pad 问题一样…

Erik St. Martin: 那么,继续这个思想实验,如果不是标准库的话,你会希望在 Go 2 中去掉语言的哪个部分或语法呢?

Brad Fitzpatrick: 我最近提议去掉复数(complex numbers)。

Erik St. Martin: 有趣。

Brad Fitzpatrick: 它们之所以存在,是因为 Ken(Ken Thompson)非常喜欢它们,但如果你查看现有的所有代码---无论是 Google 内部还是 GitHub 上---几乎没人用它们。

人们可能会为了好玩,用它们来实现曼德布罗集合(mandelbrot set)之类的东西,但除此之外,它们几乎没有什么实际用途。

(译者注: 是一种在复平面上组成分形的点的集合,以数学家本华·曼德博的名字命名)

另一方面,很多场景经常会用到大整数(bigints),而它们使用起来非常麻烦,因为你不能直接用 +- 等内置运算符;你必须调用一些方法。所以我们现在处于一个奇怪的局面,复数在 Go 中是头等公民,但几乎没人用它们,而在加密等领域经常用到的大整数却不那么容易使用。 (译者注: 深以为然)

Rob 有另一个提议是让大整数自动化。int 类型不再是 32 位机器上的 32 位,64 位机器上的 64 位,而是… int 代表大整数(bigint),并尽可能高效地实现。如果编译器能证明它永远不会超过 64 位,那么它实际上是一个 64 位的整数,但如果无法证明,它在幕后会变成一个大整数。

Erik St. Martin: 我觉得我第一个想去掉的是 new

Brian Ketelsen: newmake 的区别?

Erik St. Martin: 大部分人都不用它,所以它通常只会让新手感到困惑,对吧?我们大多数人都会直接声明一个字面值并获取它的指针。你会发现很多刚学习这门语言的人,会觉得好像有多种方式声明变量。你可以用 var name = 来声明,或者用快速声明操作符,或者用 new… 我觉得有太多种方式了,所以很难让代码保持一致。而我们总是希望代码保持一致性,对吧?所以这是我经常看到新手感到困惑的地方,他们不知道何时该用哪个,搞不清楚。

尽管我觉得看到一个空结构体字面量被声明并获取它的指针时,有点丑陋… 你没有用任何东西初始化它,为什么要使用字面量呢?Brian,你呢?有没有什么是你想第一个去掉的?

Brian Ketelsen: make… [笑声]

Erik St. Martin: 那么,你的提议是如何声明切片和数组呢?

Brian Ketelsen: 我们已经有很多方式来声明内存了… 我觉得 make 并没有增加什么,只是增加了混乱。这是来自一个教 Go 的人的观点。为什么我们必须用 make 来创建切片和映射,而声明其他东西时用 var 就可以?

Erik St. Martin: 不过,有趣的是你也可以声明容量,对吧?在某些情况下这很重要。

Brian Ketelsen: 我不是在争论它是否有用,我只是觉得应该以某种方式改变它。我没有解决方案。

Brad Fitzpatrick: 如果 Go 2 有 泛型(Generics),你可以想象切片和映射是标准库中的一种类型,你可以用 bytes.new,或者 slice.new,或者 maps.new,类似这样的方式。

Erik St. Martin: 是的,这倒是真的。

Brian Ketelsen: 你看到了吗?

Erik St. Martin: 是啊,Carlisia,你呢?你会删掉什么?

Carlisia Thompson: 我想不出什么,但是我真的很喜欢Erik的想法,把new删掉。我会投票支持这个。

Erik St. Martin: 是的,这涉及到重新思考声明的方式。当你深入了解的时候,你会发现有很多不同的方式… 很多人在使用这个语言的过程中形成了自己的一套标准做法,但…

Carlisia Thompson: 我想到一个,那叫裸返回吗?

Brian Ketelsen: 哦,对。

Carlisia Thompson: 我们应该把它去掉。

Brian Ketelsen: 这个建议不错。

Erik St. Martin: 我刚开始学Go编程的时候老是用这个,现在几乎不用了。

Brad Fitzpatrick: 是的,有点遗憾的是裸返回和命名的返回参数绑在了一起… 但对,裸返回大概可以被去掉。或者说你有一个函数,它返回一个time.Time和一个error,但你只想返回error,不关心其他参数的值;现在你必须写“return time.Time{}, error”。有各种提案允许你使用下划线_来表示任何类型的零值,或者你可以想象只返回错误error,忽略其他参数。

Erik St. Martin: 哦,这很有趣。

Brian Ketelsen: 是啊,我喜欢这个。

Erik St. Martin: 这让我想到声明的方式… 我不太喜欢空的结构体字面量,比如time.Time{}… 它没有任何上下文,因为你并没有用任何值初始化。所以如果能有一种更简洁的方式来使用零值,那就太酷了。我不知道那会是什么样子,因为我不是语言设计师,但这会很有用。

Brad Fitzpatrick: 在Go中还有一些奇怪的地方,比如在字符串上循环时,它给你的是UTF-8代码点,而不是字符串的字节,这是语言中唯一假设字符串是UTF-8的地方。所以这有点怪,还有很多这样的奇怪地方。

Erik St. Martin: 是的,这很有意思。我想这可能会成为一个问题,因为有些库假设输出是字符串而不是字节切片,所以你就会卡在这里。

Brad Fitzpatrick: 我觉得另外一个大问题是字节切片和字符串如此相似,却又如此不同,以至于我们不得不有两个包---``bytes包和strings包,而且在它们之间切换代价很高… 这真的很糟糕。

Erik St. Martin: 这种情况经常发生,因为大多数包假设你是想处理字符串,所以你的包接收字符串,然后用它作为字节切片进行一系列处理,最后返回一个字符串。但问题是,当我们把这些库组合起来时,我们就会在字符串和字节切片之间不断转换。

Brad Fitzpatrick: 其实,我很久以前有一个提案,想要改变语言和整个标准库,假设有一种类型表示可读的内存视图。字符串保证世界上任何人都不能改变它,包括你自己,而字节切片则表示你可以修改它,其他人也可能在修改它。不过,没有一种类型可以同时接受字节切片和字符串。所以我曾提出过一个内存视图类型的提案,这样你就可以写一个函数,既可以接受字节切片,也可以接受字符串,并对其进行某些操作,但你不能写入它,可能它是别人的。

Erik St. Martin: 这很有意思。所以,它可以接受字符串或字节切片,你只能读取,不能修改。

Brad Fitzpatrick: 对,我当时有个mem包,里面有一个mem.rw类型和一个mem.ro类型,分别表示可写和只读的内存类型。

Erik St. Martin: 我还挺想看看这个提案的。

Brad Fitzpatrick: 我刚刚在Slack频道里贴了一个链接,是关于它的文档。

Erik St. Martin: 好,大家准备做“自由软件星期五”吗?

Erik St. Martin: 我把沉默当作“是”的回答了。[笑声]

Carlisia Thompson: 是的,来吧。

Brian Ketelsen: 抱歉,我因为家里有电锯声静音了。

Erik St. Martin: 哦,你在搞装修?

Brian Ketelsen: 是的。

Erik St. Martin: 每周我们都会给开源项目或维护者一个致敬,表达我们的敬意。那么这周,Carlisia,你要先来吗?

Carlisia Thompson: 这周我想向Changelog网站致敬。它是一个艺术品,特别是我要感谢Jerod,因为他是这个项目的主要负责人,我尤其喜欢其中的搜索功能,真的让我很开心。如果你是听众,并且对任何与Go相关的话题感兴趣,你可以访问Changelog网站或GoTime网站,进行搜索,可能会找到一个或多个讨论该话题的节目。真的很棒。你可能会在节目注释中找到相关引用,或者发现一些讨论该主题的节目。

Brian Ketelsen: 不错!

Erik St. Martin: 你呢,Brian?

Brian Ketelsen: 我之前提到过,但我还是想再提一次,因为它真的让我很开心。Buffalo用于Web开发。用Go写网站,没有比Buffalo更快的了。今天有人在Buffalo的Slack频道里问我,是否有人在生产环境中使用它,我想天哪,我从年初开始就在GopherCon网站上使用了Buffalo,还有GopherAcademy网站,GopherTrain网站… 我可能有五六个Buffalo的网站在生产环境中运行,它们都运行得非常好。

Erik St. Martin: 看起来GopherCon和GopherAcademy的网站是任何用Go写的酷项目的试验场。我们很早就把Caddy投入使用了,它本不该在生产环境中使用的…但我们还是用它搭建了GopherCon网站…

Brian Ketelsen: 为什么不呢?我有眼光,我告诉你。

Erik St. Martin: 我们还用过Hugo来做CMS的部分…

Erik St. Martin: Brad,你有没有谁想致敬的?

Brad Fitzpatrick: 没有,我正忙着审查Carlisia的代码。[笑声]

Brian Ketelsen: 发布吧!发布吧?

Carlisia Thompson: 通过了!太棒了,谢谢!

Brad Fitzpatrick: 没问题。

Erik St. Martin: 这周我没有特别想提的项目,因为我最近没做什么新东西。我就向那些为Arduino传感器和相关库做贡献的人致敬吧,因为在最后一刻,Brian和我能够快速地拼凑出一个流式传输烧烤数据的项目,供我们烤猪时使用。

Brian Ketelsen: 太棒了,真是史诗般的体验。最棒的复活节。

Erik St. Martin: 我喜欢一些转换,不过我觉得芯片之间需要一个CRC校验,因为我不觉得四十亿度是个合理的温度。[笑声]

Brian Ketelsen: 这就是如何让皮肤焦糖化的方式。

Erik St. Martin: 对,简直就是终极慢煮。

Carlisia Thompson: 我们这次讲得这么快,难道不讨论Docker改名的事吗?(译者注: 改名为moby)

Brian Ketelsen: 不,我们不讨论Docker改名的事,我不想让我本来就高的血压再升高了。

Carlisia Thompson: 算了吧…

Erik St. Martin: [笑声]

Carlisia Thompson: 好吧。

Erik St. Martin: 那么最后,感谢今天节目的所有嘉宾,特别感谢Brad的参与。非常感谢我们今天的赞助商ToptalDatadog。请一定要和其他Go开发者、同事、朋友分享这个节目。你可以通过访问GoTime.fm订阅我们。我们也在Twitter上。如果你有话题建议、对嘉宾的问题,或者想要上节目,请到github.com/GoTimeFM/ping联系我们。好了,再见大家,我们下周见!

Brian Ketelsen: 谢谢你,Brad!

Brad Fitzpatrick: 对,谢谢!

Carlisia Thompson: 再见!