Go 博客

Go、开源、社区

Russ Cox
2015年7月8日

欢迎

[这是我在Gophercon 2015开幕主题演讲的文本。视频在此处可用。]

感谢大家远道而来丹佛,也感谢所有观看视频的人。如果这是您第一次参加Gophercon,欢迎。如果您去年来过,欢迎回来。感谢组织者为举办这样一场会议所做的一切工作。我很高兴来到这里,并能与大家交谈。

我是Go项目和Google Go团队的技术负责人。我与Rob Pike共同担任这个角色。在这个角色中,我花了很多时间思考整个Go开源项目,特别是它的运作方式,开源的意义,以及Google内部和外部贡献者之间的互动。今天我想与大家分享我对Go项目整体的看法,并在此基础上解释我对Go开源项目演变的看法。

为什么选择Go?

首先,我们必须回到最初。我们为什么要开始研究Go?

Go是为了提高程序员的生产力。我们希望改进Google的软件开发过程,但Google面临的问题并非Google独有。

有两个主要目标。

第一个目标是创造一种更好的语言,以应对可扩展并发的挑战。通过可扩展并发,我指的是同时处理许多问题的软件,例如通过来回发送网络流量协调一千个后端服务器。

今天,这种软件有一个更短的名称:我们称之为云软件。可以说,Go在云运行软件之前就已经为云设计了。

更大的目标是创造一个更好的环境,以应对可扩展软件开发的挑战,即许多人共同开发和使用的软件,他们之间协调有限,并且维护多年。在Google,我们有成千上万的工程师互相编写和分享代码,努力完成工作,尽可能多地重用他人的工作,并在一个拥有十多年历史的代码库中工作。工程师经常处理甚至查看最初由他人编写的代码,或者他们多年前编写的代码,这通常是同一回事。

Google内部的这种情况与GitHub等网站上实践的大规模、现代开源开发有很多共同之处。因此,Go非常适合开源项目,帮助他们长期接受和管理来自大型社区的贡献。

我相信Go的成功很大程度上归因于Go非常适合云软件,Go非常适合开源项目,而且,巧合的是,这两者在软件行业中都越来越受欢迎和重要。

其他人也提出了类似的观察。这里有两个。去年,在RedMonk.com上,Donnie Berkholz写了一篇关于“Go作为新兴的云基础设施语言”的文章,他观察到“[Go的]主要项目……都是以云为中心,或者专门用于处理分布式系统或瞬态环境的。”

今年,在Texlution.com上,作者写了一篇题为“为什么Golang注定成功”的文章,指出这种对大规模开发的关注可能比Google本身更适合开源:“正是这种对开源的适应性,我认为你会看到越来越多的Go……”

Go的平衡

Go是如何实现这些的?

它如何使可扩展并发和可扩展软件开发更容易?

大多数人通过讨论通道和协程、接口、快速构建、go命令以及良好的工具支持来回答这个问题。这些都是答案的重要组成部分,但我认为它们背后有一个更广阔的理念。

我把这个理念看作是Go的平衡。在任何软件设计中都存在相互冲突的关注点,并且有一种非常自然的倾向,试图解决你预见到的所有问题。在Go中,我们明确尝试不解决所有问题。相反,我们尝试做足够多的事情,以便您可以轻松构建自己的自定义解决方案。

我将Go所选择的平衡总结为:少做,多赋能。

少做,但能做更多。

Go不能做所有事情。我们不应该尝试。但如果我们努力,Go可能会做好几件事。如果我们仔细选择这些事情,我们就可以为开发人员奠定基础,使他们能够轻松构建所需的解决方案和工具,并且理想情况下,能够与其他人构建的解决方案和工具互操作。

示例

让我用一些例子来说明这一点。

首先,Go语言本身的规模。我们努力尽可能少地引入概念,以避免在大型开发社区的不同部分形成相互难以理解的方言问题。Go中没有一个想法是在简化到其本质并具有明确的、足以证明其增加复杂性的好处之前被采纳的。

总的来说,如果我们要让Go做好100件事,我们不能做100个独立的改动。相反,我们尝试研究并理解设计空间,然后确定几个能够很好地协同工作,并且能够实现其中90件事的改动。我们愿意牺牲剩下的10件事,以避免语言臃肿,避免仅仅为了解决今天看起来很重要但明天可能消失的特定用例而增加复杂性。

保持语言小巧能实现更重要的目标。小巧使Go更容易学习,更容易理解,更容易实现,更容易重新实现,更容易调试,更容易调整,更容易演进。少做能实现更多。

我应该指出,这意味着我们拒绝了很多别人的想法,但我向你保证,我们拒绝了更多我们自己的想法。

接下来,通道和协程。我们应该如何构建和协调并发和并行计算?互斥锁和条件变量非常通用,但级别太低,难以正确使用。像OpenMP这样的并行执行框架级别太高,只能用于解决狭窄范围的问题。通道和协程介于这两个极端之间。它们本身并不能解决太多问题。但它们功能强大,足以轻松安排以解决并发软件中的许多常见问题。少做——真正做到恰到好处——能实现更多。

接下来,类型和接口。拥有静态类型可以进行有用的编译时检查,这是像Python或Ruby这样的动态类型语言所缺乏的。同时,Go的静态类型避免了传统静态类型语言的许多重复,使其感觉更轻量,更像动态类型语言。这是人们最早注意到的事情之一,许多Go的早期采用者都来自动态类型语言。

Go的接口是其中的关键部分。特别是,省略Java或其他具有静态层次结构语言的“implements”声明,使得接口更轻量、更灵活。没有那种 rigid 的层次结构,可以实现诸如描述现有、不相关的生产实现的测试接口等惯用法。少做能实现更多。

接下来,测试和基准测试。在大多数语言中,测试和基准测试框架是否短缺?它们之间是否有任何共识?

Go 的 `testing` 包并非旨在解决这些主题的所有可能方面。相反,它旨在提供大多数高级工具所需的基本概念。包有通过、失败或跳过的测试用例。包有运行并可以通过各种指标衡量的基准测试。

这里“少做”是为了将这些概念简化到本质,创建一个共享的词汇表,以便更丰富的工具可以互操作。这种共识使得像 Miki Tebeka 的 go2xunit 转换器,或者 benchcmp 和 benchstat 基准分析工具这样的高级测试软件得以实现。

因为基本概念的表示存在共识,所以这些高级工具适用于所有Go包,而不仅仅是那些主动选择加入的包,并且它们可以相互操作,例如,使用go2xunit并不妨碍同时使用benchstat,就像这些工具是竞争测试框架的插件时会遇到的情况一样。少做能实现更多。

接下来,重构和程序分析。由于Go是为大型代码库设计的,我们知道它需要支持源代码的自动维护和更新。我们也知道这个主题太大,无法直接内置。但我们知道有一件事我们必须做。根据我们尝试在其他环境中进行自动化程序更改的经验,我们遇到的最主要的障碍实际上是以开发人员可以接受的格式将修改后的程序写入。

在其他语言中,不同的团队使用不同的格式约定很常见。如果程序进行的编辑使用了错误的约定,它要么写入源代码文件中看起来与文件其余部分格格不入的部分,要么重新格式化整个文件,导致不必要和不想要的差异。

Go没有这个问题。我们设计这门语言是为了让gofmt成为可能,我们努力使gofmt的格式被所有Go程序接受,并且我们确保gofmt从最初的公开发布之日起就存在。Gofmt强制执行了这样的统一性,使得自动化更改融入文件其余部分。你无法分辨某个特定的更改是由人还是计算机完成的。我们没有构建明确的重构支持。建立一个公认的格式化算法就足以作为独立工具开发和互操作的共享基础。Gofmt催生了gofix、goimports、eg和其他工具。我相信这方面的工作才刚刚开始。还可以做更多事情。

最后,构建和共享软件。在 Go 1 发布之前,我们构建了 goinstall,它演变成了我们现在都知道的 “go get”。这个工具定义了一种标准的零配置方式来解析像 github.com 这样的网站上的导入路径,后来又通过发送 HTTP 请求的方式来解析其他网站上的路径。这种约定俗成的解析算法催生了其他基于这些路径工作的工具,其中最著名的是 Gary Burd 创建的 godoc.org。如果你还没有用过,你可以访问 godoc.org/the-import-path,输入任何有效的 “go get” 导入路径,该网站就会抓取代码并显示其文档。这样做的一个很好的副作用是 godoc.org 充当了公开可用的 Go 包的大致主列表。我们所做的只是赋予导入路径明确的含义。少做,多赋能。

你会注意到,这些工具示例中的许多都与建立共享约定有关。有时人们称之为Go是“有主见的”,但更深层次的东西正在发生。同意共享约定的限制是一种能够实现广泛工具互操作的方式,因为它们都使用相同的基本语言。这是一种非常有效的“少做,多赋能”的方式。具体来说,在许多情况下,我们可以做最低限度的事情来建立对特定概念的共享理解,例如远程导入,或源文件的正确格式化,从而实现包和工具的创建,因为它们都同意这些核心细节,所以它们可以协同工作。

我稍后会回到那个想法。

Go为什么是开源的?

但首先,正如我之前所说,我想解释一下我是如何看待“少做,多赋能”的平衡在指导我们更广泛的Go开源项目工作。为此,我需要从Go为什么是开源的开始。

Google支付我和其他人从事Go的工作,因为如果Google的程序员更有效率,Google就能更快地开发产品,更容易地维护产品等等。但为什么要开源Go呢?Google为什么要与世界分享这种益处呢?

当然,我们中的许多人在Go之前就参与过开源项目,我们自然希望Go成为开源世界的一部分。但我们的偏好并非商业上的理由。商业上的理由是Go是开源的,因为这是Go能够成功的唯一途径。我们,在Google内部构建Go的团队,从第一天就知道这一点。我们知道Go必须尽可能多地提供给人们才能成功。

封闭式语言会消亡。

一种语言需要庞大而广泛的社区。

一种语言需要很多人编写大量的软件,这样当你需要某个特定工具或库时,很有可能它已经被某人编写好了,这个人比你更了解这个主题,并且比你投入了更多的时间使其变得更好。

一种语言需要许多人报告错误,以便迅速发现并修复问题。由于用户群大得多,Go编译器比它们松散基于的Plan 9 C编译器更健壮,更符合规范。

一种语言需要许多人将其用于许多不同的目的,这样该语言就不会过度适应某个用例,从而在技术格局变化时变得毫无用处。

一种语言需要很多人学习,这样才能形成一个市场,让人们写书或教授课程,或举办像这样的会议。

如果Go留在Google内部,这一切都不可能发生。Go会在Google内部,或者在任何一家公司或封闭环境中窒息而亡。

从根本上说,Go必须开放,Go需要你。没有你们所有人,没有全世界所有将Go用于各种项目的个人,Go就无法成功。

反过来,Google 的 Go 团队也永远无法足够庞大来支持整个 Go 社区。为了持续扩展,我们需要在“少做”的同时,赋能所有这些“更多”。开源是其中一个重要组成部分。

Go的开源

开源意味着什么?最低要求是开放源代码,使其在开源许可证下可用,我们已经做到了这一点。

但我们也开放了开发流程:自Go发布以来,我们所有的开发工作都在公共邮件列表上公开进行,对所有人开放。我们接受并审查来自任何人的源代码贡献。无论你是否为Google工作,流程都是一样的。我们在公共场合维护我们的错误跟踪器,我们在公共场合讨论和开发变更提案,我们公开地进行版本发布工作。公共源代码树是权威副本。变更首先发生在那里。它们只会稍后才被引入Google的内部源代码树。对于Go来说,开源意味着这是一项超越Google的集体努力,对所有人开放。

任何开源项目都是从几个人开始的,通常只有一个,但对于Go来说,有三个人:Robert Griesemer、Rob Pike和Ken Thompson。他们对Go的未来有一个愿景,认为Go可以比现有语言做得更好,Robert将在明天早上更详细地谈论这一点。我是团队中下一个加入的人,然后是Ian Taylor,然后,一个接一个,我们走到了今天,拥有数百名贡献者。

感谢所有迄今为止为 Go 项目贡献代码、想法或错误报告的人。我们今天尽力在程序中列出了所有我们能列出的人。如果您的名字不在其中,我深表歉意,但仍然感谢您。

我相信迄今为止的数百名贡献者正在为一个共同的Go愿景而努力。很难用语言来描述这些事情,但我之前已经尽力解释了愿景的一部分:少做,多赋能。

Google的角色

一个很自然的问题是:Google的Go团队与其他贡献者相比,扮演着怎样的角色?我相信这个角色随着时间的推移而改变,并且还在持续改变。总的趋势是,随着时间的推移,Google的Go团队应该做得更少,赋能更多。

在早期,在Go向公众发布之前,Google的Go团队显然是独自工作的。我们编写了所有内容的初稿:规范、编译器、运行时、标准库。

然而,Go开源后,我们的角色开始发生变化。我们需要做的最重要的事情是传达我们对Go的愿景。这很困难,我们仍在为此努力。最初的实现是传达这一愿景的重要方式,我们领导的导致Go 1的开发工作,以及我们发布的各种博客文章、文章和演讲也都是如此。

但正如 Rob 去年在 Gophercon 上所说,“语言已经完成了。”现在我们需要看看它是如何工作的,看看人们是如何使用它的,看看人们构建了什么。现在的重点是扩展 Go 可以帮助完成的工作类型。

Google的主要角色现在是赋能社区,协调,确保变更良好协同,并使Go忠于最初的愿景。

Google的主要作用是:少做,多赋能。

我之前提到,我们宁愿拥有少量特性,例如,可以满足90%的目标用例,并避免为了达到99%或100%而需要数量级更多的特性。我们已成功将该策略应用于我们熟知的软件领域。但如果Go要在许多新领域变得有用,我们需要这些领域的专家将他们的专业知识带入我们的讨论中,以便我们能够共同设计出小的调整,从而为Go实现许多新的应用程序。

这种转变不仅适用于设计,也适用于开发。Google的Go团队的角色持续更多地转向指导,更少地转向纯粹的开发。我当然花更多时间进行代码审查而不是编写代码,花更多时间处理错误报告而不是自己提交错误报告。我们需要做得更少,赋能更多。

随着设计和开发转向更广泛的Go社区,我们Go的最初作者可以提供的最重要的事情之一是愿景的一致性,以帮助Go保持Go的特性。我们必须达到的平衡当然是主观的。例如,一种可扩展语法的机制将是一种赋能更多编写Go代码的方式,但这将与我们拥有一个没有不同方言的一致语言的目标相悖。

我们有时不得不说不,可能比其他语言社区更多,但当我们这样做时,我们的目标是以建设性和尊重的态度进行,将其视为一个澄清Go愿景的机会。

当然,并非所有都是协调和愿景。Google仍然资助Go的开发工作。Rick Hudson今天晚些时候将谈论他减少垃圾回收器延迟的工作,Hana Kim明天将谈论她将Go引入移动设备的工作。但我想明确指出,我们尽可能地将Google资助的开发与由其他公司资助或个人利用业余时间贡献的开发同等对待。我们这样做是因为我们不知道下一个伟大的想法会来自哪里。所有为Go做出贡献的人都应该有机会被倾听。

示例

我想分享一些证据,证明随着时间的推移,Go团队在Google中越来越专注于协调而非直接开发。

首先,Go开发的资金来源正在扩大。在开源发布之前,显然Google支付了所有Go开发费用。开源发布后,许多个人开始贡献他们的时间,我们逐渐但稳步地增加了由其他公司支持至少兼职从事Go工作的人员数量,尤其是当这与使Go对这些公司更有用时。今天,这个名单包括Canonical、Dropbox、Intel、Oracle等。当然,Gophercon和其他区域性Go会议完全由Google以外的人组织,他们除了Google之外还有许多企业赞助商。

其次,原始团队之外的Go开发概念深度正在扩大。

开源发布后,最早的大规模贡献之一是移植到 Microsoft Windows,由 Hector Chu 发起,Alex Brainman 和其他人完成。更多贡献者将 Go 移植到其他操作系统。更多的贡献者重写了我们大部分的数值代码,使其更快或更精确,或两者兼而有之。这些都是重要的贡献,并且非常受赞赏,但大多数情况下它们不涉及新的设计。

最近,由 Aram Hăvărneanu 领导的一群贡献者将 Go 移植到了 ARM 64 架构。这是 Google 之外的贡献者首次进行的架构移植。这意义重大,因为一般来说,对新架构的支持比对新操作系统的支持需要更多的设计工作。不同架构之间的差异比不同操作系统之间的差异更大。

另一个例子是,在过去的几个版本中,我们初步支持使用共享库构建Go程序。这个功能对许多Linux发行版很重要,但对Google来说不那么重要,因为我们部署的是静态二进制文件。我们一直在帮助指导总体策略,但大部分设计和几乎所有的实现都由Google之外的贡献者完成,尤其是Michael Hudson-Doyle。

我的最后一个例子是go命令对供应商(vendoring)方法的处理。我将供应商定义为将外部依赖项的源代码复制到你的代码树中,以确保它们不会消失或在不知不觉中发生变化。

vendoring 不是 Google 面临的问题,至少不像世界其他地方那样。我们把想使用的开源库复制到我们的共享源代码树中,记录复制的版本,只有在需要时才更新副本。我们有一个规则,即源代码树中特定库只能有一个版本,而负责升级该库的人员的任务是确保它能按预期由依赖它的 Google 代码工作。这些情况很少发生。这是 vendoring 的懒惰方法。

相比之下,Google 之外的大多数项目采取更积极的方法,使用自动化工具导入和更新代码,并确保它们始终使用最新版本。

由于 Google 在处理这个问题上的经验相对较少,我们将其留给 Google 以外的用户开发解决方案。在过去的五年里,人们开发了一系列工具。目前主要使用的有 Keith Rarick 的 godep、Owen Ou 的 nut 和 Dave Cheney 的 gb 的 gb-vendor 插件。

目前的情况存在两个问题。首先是这些工具无法直接与go命令的“go get”兼容。其次是这些工具甚至彼此不兼容。这两个问题都通过工具将开发社区碎片化。

去年秋天,我们发起了一场公开的设计讨论,试图就这些工具如何运作的一些基本原理达成共识,以便它们能够与“go get”和其他工具协同工作。

我们的基本提议是,所有工具都同意在vendoring过程中重写导入路径的方法,以适应“go get”的模型,并且所有工具都同意一个文件格式,描述复制代码的来源和版本,这样即使单个项目也可以一起使用不同的vendoring工具。如果你今天使用一个,明天仍然可以使用另一个。

以这种方式寻找共同点,非常符合“少做,多赋能”的精神。如果我们能就这些基本的语义方面达成共识,那将使“go get”和所有这些工具能够互操作,并且能够实现工具之间的切换,就像Go程序在文本文件中存储方式的共识使得Go编译器和所有文本编辑器能够互操作一样。所以我们提出了共同点的建议。

发生了两件事。

首先,Daniel Theophanes 在 GitHub 上启动了一个 vendor-spec 项目,提出了一个新的提案,并接管了供应商元数据规范的协调和设计工作。

其次,社区基本上一致表示在 vendoring 期间重写导入路径是不可行的。如果代码可以在不更改的情况下复制,vendoring 会顺畅得多。

Keith Rarick 提出了一个替代方案,建议对 go 命令进行最小的修改,以支持不重写导入路径的 vendoring。Keith 的提案是无配置的,并且与 go 命令的其他方法很好地契合。该提案将作为 Go 1.5 中的实验性功能发布,并可能在 Go 1.6 中默认启用。我相信各种 vendoring 工具的作者已同意在 Daniel 的规范最终确定后采用它。

结果是,在下一次 Gophercon 上,我们应该在 vendoring 工具和 go 命令之间实现广泛的互操作性,而实现这一目标的设计完全由 Go 原始团队之外的贡献者完成。

不仅如此,Go 团队关于如何实现这一目标的提议基本上是完全错误的。Go 社区非常清楚地告诉了我们这一点。我们采纳了这条建议,现在有了一个关于 vendoring 支持的计划,我相信所有相关人员都对此感到满意。

这也是我们设计通用方法的一个很好的例子。我们尝试不对Go进行任何更改,直到我们认为对一个众所周知的解决方案达成了广泛共识。对于vendoring,来自Go社区的反馈和设计对于达到这一点至关重要。

这种代码和设计都来自更广泛的Go社区的总体趋势对Go很重要。你们,更广泛的Go社区,了解在你们使用Go的环境中什么是有效的,什么不是。我们Google不知道。我们将越来越依赖你们的专业知识,我们将努力帮助你们开发设计和代码,以扩展Go,使其在更多设置中变得有用,并与Go的原始愿景很好地契合。同时,我们将继续等待对众所周知的解决方案达成广泛共识。

这让我想到最后一点。

行为准则

我主张Go必须是开放的,Go需要你的帮助。

但事实上,Go需要每个人的帮助。而并不是所有人都在这里。

Go需要尽可能多的人提出想法。

为了实现这一点,Go社区需要尽可能地包容、热情、乐于助人、相互尊重。

Go社区现在已经足够大,以至于我及其他人认为,与其假设所有参与者都知道预期是什么,不如明确地写下这些预期。就像Go规范为所有Go编译器设定了预期一样,我们可以编写一个规范,为我们在在线讨论和像这次会议这样的线下会议中的行为设定预期。

像任何好的规范一样,它必须足够通用以允许多种实现,但又足够具体以识别重要问题。当我们的行为不符合规范时,人们可以指出,我们就可以解决问题。同时,重要的是要理解这种规范不能像语言规范那样精确。我们必须从假设我们都将合理地应用它开始。

这种规范通常被称为行为准则。Gophercon有一个,我们都在这里同意遵守,但Go社区没有。我和其他人认为Go社区需要一个行为准则。

但是它应该说什么呢?

我相信我们能做出的最重要的总体声明是,如果你想使用或讨论Go,那么你在这里,在我们的社区中是受欢迎的。我相信这是我们所追求的标准。

如果不是为了其他原因(澄清一下,还有其他很好的原因),Go需要尽可能大的社区。行为在多大程度上限制了社区的规模,就会在多大程度上阻碍Go的发展。而行为很容易限制社区的规模。

科技社区,尤其是Go社区,倾向于直言不讳的人。我不认为这是根本性的。我不认为这是必要的。但在在线讨论,如电子邮件和IRC中,尤其容易出现这种情况,因为纯文本没有像我们面对面互动中那样的其他线索和信号作为补充。

例如,我了解到,当我时间紧迫时,我倾向于写更少的词,最终导致我的电子邮件看起来不仅匆忙,而且直率、不耐烦,甚至轻蔑。这不是我的感受,但这是我可能给人的印象,而这种印象足以让人们在使用或贡献Go之前三思。我意识到我这样做是因为一些Go贡献者私下发邮件告诉我。现在,当我时间紧迫时,我会特别注意我正在写的内容,而且我通常会写得比我自然而然的要多,以确保我发送的是我想要传达的信息。

我相信,纠正我们日常互动中,无论是故意的还是无意的,那些赶走潜在用户和贡献者的部分,是我们确保Go社区持续发展可以做的最重要的事情之一。一个好的行为准则可以帮助我们做到这一点。

我们没有编写行为准则的经验,所以我们一直在阅读现有的准则,我们可能会采纳一个现有的准则,或许会进行 minor 调整。我最喜欢的是 Django 行为准则,它起源于另一个名为 SpeakUp! 的项目。它的结构是对日常互动提醒列表的详细阐述。

“友善和耐心。热情好客。体贴周到。尊重他人。谨慎选择词语。当我们意见不合时,努力理解原因。”

我相信这抓住了我们想要设定的基调,我们想要传递的信息,我们想要为新贡献者创造的环境。我当然想做到友善、耐心、热情、体贴和尊重。我不会每次都做得完全正确,如果我没有做到,我将乐意接受善意的提醒。我相信我们大多数人都有同感。

我没有提及基于或不成比例地影响种族、性别、残疾或其他个人特征的积极排斥,也没有提及骚扰。对我来说,从我刚才所说的来看,排斥行为或明确的骚扰在线上线下都是绝对不可接受的。每一个行为准则都明确说明了这一点,我预计我们的也会如此。但我相信 SpeakUp! 关于日常互动的提醒同样重要。我相信,为这些日常互动设定高标准,可以使极端行为变得更加清晰和容易处理。

我毫不怀疑,Go社区可以成为科技行业中最友好、最热情、最体贴、最受尊重的社区之一。我们可以做到这一点,这将对我们所有人都有益和值得称赞。

Andrew Gerrand 一直在领导为 Go 社区制定适当行为准则的工作。如果您有建议、疑虑、行为准则方面的经验,或者希望参与,请在会议期间寻找 Andrew 或我。如果您周五仍在这里,Andrew 和我将在 Hack Day 期间留出一些时间进行行为准则讨论。

再次强调,我们不知道下一个好主意会从哪里来。我们需要尽一切可能提供帮助。我们需要一个庞大、多元化的Go社区。

谢谢

我认为许多使用“go get”发布软件供下载、通过博客文章分享见解,或在邮件列表或IRC上帮助他人的个人,都是这一广泛开源工作的一部分,是Go社区的一部分。今天在座的各位也都是这个社区的一部分。

预先感谢在接下来的几天里抽出时间分享他们使用和扩展Go的经验的演讲者。

预先感谢在座的各位抽出时间来到这里,提出问题,并让我们知道Go对您来说如何工作。当您回家后,请继续分享您所学到的。即使您不将Go用于日常工作,我们也希望看到Go的成功经验被其他环境采用,就像我们一直在寻找好的想法带回Go一样。

再次感谢大家为来到这里并成为Go社区的一员所做的努力。

在接下来的几天里,请:告诉我们我们做对了什么,告诉我们我们做错了什么,并帮助我们所有人一起努力,让Go变得更好。

请记住要友善、耐心、热情、体贴和尊重。

最重要的是,享受这次会议。

下一篇文章:GopherCon 2015 综述
上一篇文章:奇虎360与Go
博客索引