2017/08/06
每次blog.golang.org更新博客,我都迫不及待去读一下;最新的一篇,  Contributors Summit,记录了Go贡献者们的一些讨论。我读到一句话,让我感觉得有必要写这个Blog:
For instance, it would be nice if io.Reader accepted a context so that blocking read operations could be canceled.(io.Reader接收一个context来取消阻塞的读操作是一个不错的主意)
本人瞬间惊呆了,这样一来,io.Reader将会是这样:
type Reader interface { Read(ctx context.Context, p []byte) (n int, err error) }
我搜索了一下,发现已经有人向Go2提了这个修改;谢天谢天大多数人并不认可( proposed this change )
这篇博客将会讨论所有有关“context”的错误(其实 context还是挺有用的 ),以及Go2需要为它做些什么。
Go是一门通用的语言
首先我们要明确,Go是一个很好的开发Server程序的语言,但Go并不是专为写Server程序而生。Go是一门通用的语言,就像c,c++,java或python一样。比如我已经使用Go两年了,但却没有写过一个Server程序。
因此,我们要以设计一门通用语言的角度来设计Go及其标准库。现在,我想说的是context只适写Server的人,至少大多数情况下如此。
Context像病毒一样传染
这是context最主要的问题:它会传染!正如这篇博客中所说的( this blog post about the context package)
At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests.
(在谷歌,我们要求把context应用到请求从输入到输出所流经的所有函数上面)
所有的这些函数都需要传递一个context进去,否则它可能不能被完全Cancel掉。这意味着所有调用的其它库的函数也需要接收context。
简而言之,如果你想写一个库,而这个库会被其它的Server程序调用到,那么你就需要在函数中加入context参数!
这就是context如何像病毒一样传播。这样有什么坏处呢,我们来看一下:
1.Go是一门通用的语言
2.如果一个库会被Server程序调用,它就需要接收context。
3.现在,每个人必须处理context,即使你并不需要它。
当然,你可以到处传递context.TODO(),但这简单太糟糕了,它破坏了代码的可读性,让代码看起来丑陋无比,泯灭了我写Go代码的乐趣。
如果某天我不得不写出这样的代码:
n, err := r.Read(context.TODO(), p)
那伙计麻烦给我把枪,让我们Say Goodbye.
你也许会辩解:一个库可以为每个函数提供两个版本,一个带context一个不带。额……是的,  "database/sql"包就这样做了。尽管它部分解决了这个问题,但看起来很糟糕(不够优雅啊)
并且,如果去给学生们教授Go语言,你开始讲解context版的io.Reader接口。学生们问:ctx context.Context是什么东西老师?答案可能会这样:不要管这个,只要传个context.TODO()进来就行了。听起来像 public static void给我的感觉。
这里的主要观点是:Context会像病毒一样传播,当我不需要它的话,我不想处理它。
“context”包本身的实现并不好。
这是一个个人观点。对我来说,context.Context接口有过多的方法。但更主要的问题是:
在我的公司里使用ctx.Value,你就会被炒鱿鱼!
我不知道是谁想出这个想法让context带上一个无意义的map,(object->object的映射),这有太多问题,我们来列举之:
1.很明显的一个,它不是静态类型;
2.它需要记录,哪些Value是哪个函数支持和使用的。我们知道,documentation是永远不会执行的代码。
3.它跟thread-local存储类似。我们知道thread-local存储是多么糟糕的想法。不灵活,使用,测试复杂
4.这不常发生,但是会发生名称冲突。
5.这像一个容易出错的魔法。
我知道,ctx.Value会使一些东西实现起来简单。但是我相信,设计API时不使用ctx.Value,你也一定会有替代方案。
Context是一个低效的链表。
WithCanel,WithDeadline工作需要创建链表。我们需要给WithCancel创建一个goroutine,将cancel信号由前一个context传递到下一个。当然如果context一直没被取消,goroutine就一直存在(相当于resource leak作者认为)
最后:
ctx context.Context
就像
Foo foo = new Foo();
一样,是Go设计中就极力避免的东西( created to avoid.)。
"context"包实际解决了什么问题?
即使有这么多的问题,"context"依然是很有用的,因为它解决了Go里面很难处理的一个问题:cancelation(取消)。这是"context"唯一所解决的问题。
我们正视现实,Go里面的取消很难实现。在
‘Advanced Go Concurrency Patterns’中有一个很全面和深入的讨论。这个讨论发生在context包引入到Go中之前。因此它讨论的是使用channel来解决cancelation的问题。
这个讨论中所提出的解决方案没有可伸缩性,原因如下:
1.cancelation使用的channels不能传递到其它的库或函数,因此只有在内部自己使用。
2.想像一个goroutine的树(子gotoutine由父生成),要结束所有的goroutine很容易,只要将cancelation channel关闭即可。但是要结束一个子树却很难。(你需要使用另一个channel,或其它解决方法)
"context"解决了这个问题,虽然效率低下且存在很多问题。但这个解决方法却要比已存在的其它办法要好。
go里我们必须要解决cancelation的问题。当我们使用goroutine时这是必要的。
Go2必须正视cancelation的问题!
我认为Go提供一个"context"这样的包,本身就是个错误。Go设计的很简单的实现了创建goroutine并在他们之间通信,但是"context"证明Go将goroutine的取消实现的很难用。我认为这个问题需要在语言层面来解决。Go需要在语言层面提供一个解决方案,达到:
1.简单,优雅
2.可选 ,非侵入,并非传染
3.健壮,高效
4.只解决cancelation的问题。像Values的功能可以省略了。可以在非常简单的cancelation上实现超时功能。
你可能会说:我喜欢context,它不需要改变或使Go语言复杂化,而优雅的解决了这个问题。我不同意。就像所有上面所说的,它不是一个优雅的解决方案,尽管cancellation不是这个语言不可获缺的一部分,但它会变得越来越重要。
我想了几种解决方案,但我会在另一篇博客中来写,或者如果有人提出更好的解决方案我会自己保留。这篇博客的目的是指出这个问题。
结论:
这篇博客试图指出Go语言存在的问题。简而言之,Go语言存在cancelation难的问题,并且"context"包没有很好的解决这个问题。除了语言层面,我没有想出其它解决这个问题的方法。交给Go2来做吧!

转载于:https://www.cnblogs.com/gm-201705/p/8186317.html

【翻译】Context should go away for Go 2相关推荐

  1. CVPR2020论文翻译 Context Prior for Scene Segmentation

    CVPR2020: Context Prior for Scene Segmentation 题目:场景分割的上下文先验 论文地址:https://arxiv.org/pdf/2004.01547.p ...

  2. QColorDialog中Pick Screen Color、Ok、Cancel不能汉化解决

    在Qt安装目录下的Src下找到对应的qt_zh_CN.qm文件,复制到当前项目的资源文件夹中,并添加到资源中 –如果没有,则找到文件qt_zh_CN.ts,复制到当前项目中,用lrelease生成qt ...

  3. vscode 添加新建文件夹快捷键 (配置 when 属性)

    实现目标 在获取左侧项目栏文件夹焦点情况下 添加新建文件夹的快捷键 Shift + A 我本来是个atom忠实粉丝, 但是atom使用window10自带输入法在书写汉字时总是会出现首字母缺失的情况, ...

  4. SOUI总结之常用功能

    常用功能 XML特殊字符显示 空格 ( ) Tab ( ) 回车 ( ) 换行 ( ) & (&) < (<) > (>) ' (') " (&quo ...

  5. XSL 和 XSLT的区别

    <XSL扩展标记语言> 1.CSS = HTML 样式表 XSL = XML 样式表 2.XSL 包括三部分: XSLT:一种用于转换 XML 文档的语言. XPath:一种用于在 XML ...

  6. 用XPath精确定位节点元素selenium使用Xpath定位之完整篇

    用XPath精确定位节点元素&selenium使用Xpath定位之完整篇 用XPath精确定位节点元素&selenium使用Xpath定位之完整篇 在利用XSL进行转换的过程中,匹配的 ...

  7. golang设计模式——行为模式

    文章目录 简介 模版模式 通俗解释 概念 应用场景 优点 缺点 实例演示 总结 命令模式 通俗解释 概念 应用场景 优点 缺点 实例演示 1 将函数封装为对象 2 将函数直接作为参数 总结 迭代器模式 ...

  8. 翻译 | Placing Search in Context The Concept Revisited

    翻译 | Placing Search in Context The Concept Revisited 原文 摘要 [1] Keyword-based search engines are in w ...

  9. Context的翻译

    在开发中,"context"这个词经常发出,但搜一下,发现对"context"这个词的翻译,一般都是"上下文",但,这个中文翻译确实让人费解 ...

  10. Context Prior for Scene Segmentation论文阅读/翻译

    Context Prior for Scene Segmentation论文阅读/翻译 论文地址 Abstract Introduction Context Prior Affinity Loss C ...

最新文章

  1. Numpy 一维、二维数组、size/dtype/shape属性、数组函数arange/linspace/logspace /diag/zeros/ones/random 、多维数组索引和筛选)
  2. mysql索引查2遍_mysql索引优化查询
  3. java 打印一棵树_java编程题之从上往下打印出二叉树
  4. [leetcode]617.合并二叉树
  5. Android 9.0新特性
  6. 什么浏览器好用_手机浏览器不只UC,好用的浏览器还有这些
  7. 李飞飞:一站式全链路数据管理与服务成为产业布局重点
  8. iPhone 13 mini背部新外观曝光:双摄对角线排布
  9. windows temp用户问题
  10. html中怎么消除排序的前缀,北京web前端培训-解决css3前缀问题的插件-Autoprefixer...
  11. 全球五十家知名传感器制造商分布盘点、特点分析
  12. zotero抓取知网文献
  13. 金蝶K3开发-工业老单据序时薄隐藏列内容
  14. 解决Win10无操作两分钟进入睡眠问题
  15. Linux 文本三剑客之awk 木石前盟
  16. 学生静态网页设计作品之我的家乡
  17. unity运行时修改光源的颜色,变成白色
  18. storm风暴英雄 tempo_【风暴英雄】锐派专区 - fb.replays.net | 风暴英雄官网合作中文站...
  19. echarts中在地图上显示label时的阴影问题
  20. ubuntu下flann库编译报错处理

热门文章

  1. 11月在华出货量暴跌35%,苹果手机或成第二个三星
  2. 我的算法不可能这么简单—珂朵莉树
  3. 怎么样在excel表格里面每隔一行插入一个空行
  4. 创新型数码管理软件系统
  5. 列车节能优化软件V1.0
  6. 简易自制冰淇淋(本来想叫朗姆酒冰淇淋,酒好像挥发了)
  7. Angular学习(4)- 数组双向梆定
  8. 病毒分析——静态特征分析 及 动态行为分析
  9. 老域名的好处 新网站快速收录排名
  10. 车载软件架构——AUTOSAR的江湖夜雨十年灯