我的2017年Go决议

一年之季始于春,我认为写一些今年我希望在Go上做的东西是有意义的。

我每年的目标是帮助Go开发人员。我想确保我们在Go团队中所做的工作对Go开发者有重大的积极影响。可能听起来很明确,但是有各种常见的方面无法实现这一点:例如,花费太多的时间清理或优化不需要的代码;仅响应最常见或最近的抱怨或请求,或者重点关注短期改进。重要的是退后一步,确保我们将开发工作重点放在最好的地方。

这篇文章概述了我今年关注的几大重点。这只是我的个人清单,不是Go团队的清单。

发布这个的一个原因是收集反馈。如果这些引发了你自己的任何想法或建议,请随时在下面或链接的github问题上发表评论。

另一个原因是要明确我意识到这些问题很重要。我经常认为Go团队的缺乏行动是由于我们认为一切都是完美的,而不只是其他一些较高优先级的工作要先做。

类型别名

在大型代码库重构期间有个经常性问题:将类型从一个包移动到另一个包。去年我们试图用通用的别名来解决这个问题,没有成功的原因有两个:我们没有足够的解释这个变化,我们按时交付,所以Go 1.8中没有准备好别名。从这方面的经验学习,我做了一个谈话,写了一篇关于底层问题的文章,在Go issue tracker上展开了富有成效关于解决方案空间的讨论。看起来有限类型别名是正确的下一步,我想确保这些在Go 1.9中顺利落地。 #18130

包管理

我在2010年2月设计了Go支持下载已发布的软件包(“goinstall”,成为”go get”)。自那时以来发生了很多事情。特别是,其他语言生态系统真正提高了人们对包管理的期望,开源世界大多同意语义版本化,这为推断版本兼容性提供了有用的基础。Go需要在这里做得更好,一些贡献者一直在研究解决方案。我想确保这些想法被集成到标准的Go工具链中,并使包管理成为人们喜欢go的一个原因。

构建改进

在Go命令的构建系统的设计中有一些缺点,它们早就应该被解决。有三个代表性的例子,我打算通过一些重新设计go命令的内部结构来解决。

构建可能太慢,因为go命令不会像应用程序一样积极地缓存构建结果。许多人没有意识到,go install保存它的工作但go build没有,他们运行多次go build命令是慢的,因为后续的构建做了许多不必要的工作。当依赖被修改时,没有使用go test -i的重复go test命令有同样的问题。所有的构建应该尽可能增量。 #4719

测试结果也应该缓存:如果测试的输入都没有改变,那么通常没有必要重新运行测试。这将使得当没有或很少修改时运行”all tests”非常便宜。#11193

GOPATH之外的工作应该与GOPATH之内的工作几乎一样。特别是,应该可以git clone一个repo,切换到目录(cd into it),运行go命令,并使他们正常工作。软件包管理只会使这更重要:你需要能够处理不同版本的软件包(例如V1和V2),而不需要为他们提供完全独立的GOPATH #17271

代码库集

我认为这有助于我在准备关于代码库重构(见上面)的谈话和文章中有来自真实项目中的正确例子。我们还定义了vet添加必须针对实际程序中经常发生的问题。我想看到真实实践中的这种分析--检查对真实程序的影响和可能的改进--成为我们讨论和评估Go的变化的标准方法。

现在还没有一个约定的有代表性的代码库全集来用于这些分析:每个人必须首先创建自己的,这需要太多的工作。我想组成一个单一的,自包含的git repo,人们可以为这些分析检出包含我们的官方基准全集。可以从github上前100个按stars或forks或两者排名的go语言代码库开始。

自动vet

Go发布包包含这个强大的工具,go vet,可以指出正确性缺陷。检查的门槛很高,所以你应该听vet的话。但每个人都必须记住运行它。如果你不必记住会更好。特别是,我认为我可以在go tes的测试二进制文件的最终编译和链接期间并行运行vet,而不会使compile-edit-test的周期变慢。如果我们可以做到这一点,如果我们启用的vet检查限制在基本100%正确的子集,那么我们可以通过vet来完成一个运行测试的前提条件。那么开发人员不需要记得去运行go vet。他们运行go test,偶尔vet会报告一些重要的事情,可以避免调试会话。  #18084  #18085

Errors & best practices

Go中错误报告的预期契约的一部分是这些功能:包含有效的上下文,包含正在尝试的操作(例如函数名称及其参数)。例如,这个程序:

err:=os.Remove(“/tmp/nonexist”)

fmt.Println(err)

打印输出:

remove /tmp/nonexist: no such file or directory

没有太多的Go代码添加像os.Remove那样的上下文。太多代码只做了

if err != nil {

return err

}

整个调用堆栈都是这样子,丢弃了应该报告的有用上下文(如上面的 remove /tmp/nonexist),我想了解我们对包含上下文的期望是否错误,或者我们可以做些什么来使编写返回更好错误的代码更容易。

社区还有许多关于剥离错误上下文的商定接口的讨论。我想尝试了解什么时候有意义,以及我们是否应该采取官方建议。

Context & best practices

我们在Go 1.7中添加了新的context包,用于保持请求范围内的信息,如超时、取消状态和凭据。单个上下文是不可变的(像一个单独的string或int):只能导出一个新的,修改的上下文,并将该上下文明确地向下传递给调用堆栈,或者(不太常见)反向传给调用者。上下文现在通过诸如database/sql和net/http之类的API携带,主要是因为当调用者对结果不关心时可以停止处理请求。超时信息适合在上下文中携带,但是,使用我们移除的真实例子,数据库选项不是,因为他们不太可能同样地应用于所有可能的数据库操作请求。关于当前的clock source和logging sink呢?是否适合在上下文中存储?我想尝试理解和描述适合或不适合使用上下文的标准。

内存模型

Go的内存模型是有意低调的,与其他语言相比,对用户的承诺很少。事实上,它首先是阻止人们阅读文档的余下部分。同时,它对编译器的要求比其他语言多:特别是,一个整形值的竞争不足以让您的程序以任意方式表现异常。但也有一些完全差距,特别没有提到sync/atomic包。我认为核心的编译器和运行时开发者都同意这些 atomics包的行为应该与C++ seqcst atomics或java volatiles一样,当我们还是要在内存模型中仔细地写下来,也可能在一个长的博客。  #5045 #7948  #9442

Immutability

竞争检测器(race detector)是Go中最受欢迎的一个特性之一。但没有竞争(race)会更好。如果有一些合理的方式将参考不可变性(immutablility)整合到go,我会喜欢它,以便程序员可以清楚,检查断言关于什么可以或不可以写,从而在编译期消除竞争。Go已经有一个不变类型,string;追溯定义string为不可变[]byte的命名类型(或类型别名)会更好。我不认为今年会发生,但我想更好地了解解决方案空间。Javari,midori,pony和 rust都在方案领域内解决了一些重要问题,除此之外还有大量的研究论文。

长远来看,如果我们可以静静地消除竞争的可能,那就可以消除对大多数内存模型的需要。这可能是一个不可能的梦,但我又想更好地了解解决方案空间。

Generics 泛型

Go和非go开发者之间,没有什么会比go是否应该支持泛型(或几年前应该发生的问题)引发更激烈的争论。我不相信Go团队曾经说过“Go 不需要泛型”,我们所说的是,面临着更高优先级的问题。例如,我们对包管理的更好的支持对大多数go开发者来说比添加泛型会产生更大更直接的正面影响。但我们确实知道,对于某些子集的Go用例,缺少参数多态性是一个显著的障碍。

就我个人而言,我想能够编写通用的通道处理功能,如:

// Join makes all messages received on the input channels

// available for receiving from the returned channel.

func Join(inputs ...<-chan T) <-chan T

// Dup duplicates messages received on c to both c1 and c2.

func Dup(c <-chan T) (c1, c2 <-chan T)

我也希望通过编译时而不是在运行时捕获类型错误的方式,可以为高级数据处理抽象写入go支持,类似于FlumeJava或c#的LINQ。还可以编写任何数量的数据结构或通用算法,但是我个人认为这些更广泛的应用程序更具吸引力。

我们多年来一直在努力找到正确的方法来为go添加泛型。至少有一些过去的提案被挂起,试图设计提供一般参数多态(如chan T)已经string和[]byte的统一的东西。如果后者通过对不可变性的参数来处理,如上一节所述,那么也许简化了泛型设计的需求。

当我在2008年第一次开始考虑go的泛型时,要学习的主要例子是C#,Java,haskell和ML。在这些语言中,没有一种方法似乎完全适合Go。今天,还有更新的尝试,包括Dart,Midori,Rust和Swift。

我们大胆探索设计空间已经有几年了。这可能是再次环顾的时候了,特别是鉴于对可变性的了解以及由更新语言的附加示例集。今年我并不任务泛型会发生,但是我想能够更好地理解解决方案空间。

My Go Resolutions for 2017(from Russ cox's blog)的更多相关文章

  1. Python之旅:入门

    一 编程与编程语言 python是一门编程语言,作为学习python的开始,需要事先搞明白:编程的目的是什么?什么是编程语言?什么是编程? 编程的目的: #计算机的发明,是为了用机器取代/解放人力,而 ...

  2. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

  3. Go 语言的下一个大版本:Go 2.0 被安排上了(全面兼容1.X,改进错误处理和泛型这两大主题)

    今年 8 月 Go 开发团队公布了 Go 2.0 的设计草案,包括错误处理和泛型这两大主题.现在备受瞩目的 Go 2.0 又有了新动向 —— 昨日 Go 开发团队在其官方博客表示,Go 2 已经被安排 ...

  4. 编程语言与Python学习(一)

    1.1 编程与编程语言 1.1.1 编程语言 计算机的发明,是为了用机器解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而达到让计算机能够像人脑一样自动执行 ...

  5. Golang error 的突围

    目录 error 的困局 尝试破局 Errors are just values handle not just check errors Only handle errors once 小结 胎死腹 ...

  6. 深度解密Go语言之 pprof

    目录 什么是 pprof pprof 的作用 pprof 如何使用 runtime/pprof net/http/pprof pprof 进阶 Russ Cox 实战 查找内存泄露 总结 参考资料 相 ...

  7. py-1 语言介绍

    一.编程与编程语言 1.编程的目的 计算机的发明,是为了用机器取代并解放人力.而编程的目的则是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而达到让计算机能够像人脑.电脑一样自动执 ...

  8. Go 开发关键技术指南 | 敢问路在何方?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 Go 开发关键技术指南文章目录: 为什么你要选择 Go? Go 面向失败编程 带着服务器编程金刚经走进 2020 年 敢问路在何方? Go 开发指南大图 ...

  9. GoCenter助力Golang全速前进

    一.背景 Go语言是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言.为了方便搜索和识别,有时会将其称为Golang.自2009年11月Google正式宣布推出,成为开放 ...

随机推荐

  1. 用vue2.x注册一个全局的弹窗alert组件

    一.在实际的开发当中,弹窗是少不了的,默认系统的弹窗样式太丑,难以满足项目的实际需求,所以需要自己定义弹窗组件,把弹窗组价定义为全局的,这样减少每次使用的时候引入麻烦,节省开发时间.本文将分享如何定义 ...

  2. POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13955   Accepted: 5896 Desc ...

  3. sublime text 3 ctrl+b浏览器启动html

    sublime text 2 和3 都可以快速设置浏览器启动,本人在这里介绍如何不下插件启动浏览器.第一步:打开Tool-->build system  ---> new build sy ...

  4. JAVA IO分析一:File类、字节流、字符流、字节字符转换流

    因为工作事宜,又有一段时间没有写博客了,趁着今天不是很忙开始IO之路:IO往往是我们忽略但是却又非常重要的部分,在这个讲究人机交互体验的年代,IO问题渐渐成了核心问题. 一.File类 在讲解File ...

  5. 班级博客客户端Beta阶段发布说明

    班级博客客户端Beta阶段发布说明 NewTeam 2017/12/18 项目 博客园班级博客Android客户端 目录 发布方式和发布地址 新功能 修复的缺陷 对运行环境的要求 安装方法 已知的问题 ...

  6. Linux 容器 vs 虚拟机 —— 谁更胜一筹

    自从Linux上的容器变得流行以来,了解Linux容器和虚拟机之间的区别变得更加棘手.本文将向您提供详细信息,以了解Linux容器和虚拟机之间的差异. Linux容器vs虚拟机 – 应用程序与操作系统 ...

  7. oralce11g导出dmp然后导入Oracle10g

    一次Oracle11g数据库导入 Oracle10g数据库操作笔记 11g备份导入10g的时候会抛错直接阻止导入. 但是有时候还必须得把11g的数据库导入到10g我今天就遇到了这种情况. 一开始 ...

  8. 这是我对GET与POST的区别的回答

    不知在哪里看到的这种答案,之前很长一段时间对GET与POST的区别理解如下 一是GET数据附加在URL之后,是显示的,不安全的,POST反之. 二是数据大小限制,GET受URL长度限制,数据有限,PO ...

  9. Linux 账号管理与 ACL 权限配置

    要登陆 Linux 系统一定要有账号与口令才行,否则怎么登陆,您说是吧?不过, 不同的使用者应该要拥有不同的权限才行吧?我们还可以透过 user/group 的特殊权限配置, 来规范出不同的群组开发项 ...

  10. poj Minimum( CutStoer Wagner算法)

    Minimum Cut 题目: 给出一张图.要求你删除最小割权和图. 算法分析: ////////////////////     转载 --- ylfdrib   ///////////////// ...