zoukankan      html  css  js  c++  java
  • My Go Resolutions for 2017(from Russ cox's blog)

                              我的2017Go决议

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

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

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

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

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

    类型别名

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

    包管理

    我在20102月设计了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命令,并使他们正常工作。软件包管理只会使这更重要:你需要能够处理不同版本的软件包(例如V1V2),而不需要为他们提供完全独立的GOPATH #17271

    代码库集

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

    现在还没有一个约定的有代表性的代码库全集来用于这些分析:每个人必须首先创建自己的,这需要太多的工作。我想组成一个单一的,自包含的git repo,人们可以为这些分析检出包含我们的官方基准全集。可以从github上前100个按starsforks或两者排名的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包,用于保持请求范围内的信息,如超时、取消状态和凭据。单个上下文是不可变的(像一个单独的stringint):只能导出一个新的,修改的上下文,并将该上下文明确地向下传递给调用堆栈,或者(不太常见)反向传给调用者。上下文现在通过诸如database/sqlnet/http之类的API携带,主要是因为当调用者对结果不关心时可以停止处理请求。超时信息适合在上下文中携带,但是,使用我们移除的真实例子,数据库选项不是,因为他们不太可能同样地应用于所有可能的数据库操作请求。关于当前的clock sourcelogging sink呢?是否适合在上下文中存储?我想尝试理解和描述适合或不适合使用上下文的标准。

    内存模型

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

    Immutability

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

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

    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支持,类似于FlumeJavac#LINQ。还可以编写任何数量的数据结构或通用算法,但是我个人认为这些更广泛的应用程序更具吸引力。

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

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

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

  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/majianguo/p/6816730.html
Copyright © 2011-2022 走看看