gofmt 的文化演变.pdf

上传人:yyf 文档编号:3330213 上传时间:2019-08-13 格式:PDF 页数:34 大小:9.97MB
返回 下载 相关 举报
gofmt 的文化演变.pdf_第1页
第1页 / 共34页
gofmt 的文化演变.pdf_第2页
第2页 / 共34页
gofmt 的文化演变.pdf_第3页
第3页 / 共34页
gofmt 的文化演变.pdf_第4页
第4页 / 共34页
gofmt 的文化演变.pdf_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《gofmt 的文化演变.pdf》由会员分享,可在线阅读,更多相关《gofmt 的文化演变.pdf(34页珍藏版)》请在三一文库上搜索。

1、4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#11/34 gofmt 的文化演变 The Cultural Evolution of gofmt Robert Griesemer Google, Inc. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#12/34 gofmt Go源代码格式化工具 定义了“标准“格式 golang.org代码库中所有提交的Go代码都必须通过gofmt格式化过 除了gofmt之外,相同功能可以通过go/format库获得 不需

2、要设置! 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#13/34 初衷 代码审查是软件工程的最佳实践 代码审查是基于代码规范和正规格式的 太多时间浪费在审查格式上而不是代码本身了 但是这工作对机器来说是最好不过了的 第一个决定就是要写一个好的格式美化器 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#14/34 历史 格式美化器和代码美化工具在计算机发展的早期就已出现 对于产生可读的Lisp代码很重要的: G R I N D E F ( B i l l G

3、 o s p e r , 1 9 6 7 ) 第一个计算行长度 其他: S O A P ( R . S c o w e n e t a l , 1 9 6 9 ) 简化了晦涩的算法程序 N E A T E R 2 ( K e n C o n r o w , R . S m i t h , 1 9 7 0 ) P L 1 格式器,作为(早期的)纠错工具 c b ( U n i x V e r s i o n 7 , 1 9 7 9 ) C 程序美化器 i n d e n t ( 4 . 2 B S D , 1 9 8 3 ) 缩进和格化化C 代码 等等 最近的: C l a n g F o r

4、m a t C / C + + / O b j e c t i v e - C 格式器 U n c r u s t i f y C , C + + , C # , O b j e c t i v e C , D , J a v a , P a w n a n d V A L A 的美化器 等等 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#15/34 事实上 在2007年,没人喜欢代码格式器 例外:IDE强制的格式化 但是:很多程序员不用IDE. 问题:如果是格式化太具有毁坏性,那么就没有人会用 被忽视的观点:“刚刚好“的,

5、统一化的格式是好过于各种不同的格式的。 规范的价值在于:整齐划一,而不是完美 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#16/34 好的格式美化器的问题 当越多人思考他们自己的格式风格的时候,他们就变得更加固执于此了 错误的结论:自动格式器必须要有很多选项! 但是有很多选项的格式器其实违背他们的目的 此外,支持很多选项是难的 尊重用户的想法是最关键的 处理注释是很难的 语言本身也会增加很多额外的复杂度(比如,C的宏) 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.

6、slide#17/34 格式化Go 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#18/34 尽量保证其简单 小的语言能让事情变得简单 不要为行长度烦恼 相反的,尊重用户:考虑原有代码中的断行 不要支持任何选项 使其使用傻瓜化 一个格化标准搞定所有! 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#19/34 gofmt的基本结构 源代码的处理 基本的格式化 附加:注释的处理 完善:代码和注释的对齐 但是,没有牛X的通用布局算法 相反的:基于节点的精细优化

7、4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#110/34 处理源代码 使用go/scanner, go/parser及其相关的库 给每一个go文件生成一个抽象语法树 每一个语法结构都有相应的AST节点 / / S y n t a x o f a n i f s t a t e m e n t . I f S t m t = “ i f “ S i m p l e S t m t “ ; “ E x p r e s s i o n B l o c k “ e l s e “ ( I f S t m t | B l o c k

8、 ) . / / A n I f S t m t n o d e r e p r e s e n t s a n i f s t a t e m e n t . I f S t m t s t r u c t I f t o k e n . P o s / / p o s i t i o n o f “ i f “ k e y w o r d I n i t S t m t / / i n i t i a l i z a t i o n s t a t e m e n t ; o r n i l C o n d E x p r / / c o n d i t i o n B o d y * B

9、 l o c k S t m t E l s e S t m t / / e l s e b r a n c h ; o r n i l AST节点有(选择性的)位置信息。 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#111/34 基本的格式化 遍历AST然后打印每个节点 c a s e * a s t . I f S t m t : p . p r i n t ( t o k e n . I F ) p . c o n t r o l C l a u s e ( f a l s e , s . I n i t , s .

10、 C o n d , n i l ) p . b l o c k ( s . B o d y , 1 ) i f s . E l s e ! = n i l p . p r i n t ( b l a n k , t o k e n . E L S E , b l a n k ) s w i t c h s . E l s e . ( t y p e ) c a s e * a s t . B l o c k S t m t , * a s t . I f S t m t : p . s t m t ( s . E l s e , n e x t I s R B r a c e ) d e f

11、 a u l t : p . p r i n t ( t o k e n . L B R A C E , i n d e n t , f o r m f e e d ) p . s t m t ( s . E l s e , t r u e ) p . p r i n t ( u n i n d e n t , f o r m f e e d , t o k e n . R B R A C E ) 打印器(p.print)接收包括位置和空格符等的一系列记号 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#112/34 细致的调

12、节 基于优先级安排操作数之间的空格. 提高表达式的可读性. x = a + b x = a + b * c i f a + b 0 成组的注释被处理为一个大的注释. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#114/34 注释在 AST 上的表达 注释组的连续列表被连接到 AST 的文件节点. 另外,一些被标示为 doc strings 的注释被连接到声明节点. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#115/34 格式化注释 基本的办法:基于位

13、置信息合并词汇流和注释流. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#116/34 魔鬼就在细节中 在源代码中估计当前的位置. 比较当前的位置和注释的位置去决定下一个是什么. 词汇也包含了空格词汇 - 注释必须被合理的分布! 维持一个未被打印的空格缓冲区,在下一个词汇之前输出,然后分布注释. 多种策略得以正确地处理空格. 很多次的尝试和错误. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#117/34 格式化单独的注释 区分代码行和注释. 努力对多行注

14、释进行合理的缩进. f u n c f ( ) f u n c ( ) / * / * * f o o * f o o * b a r = = * b a r * b a l * b a l * / * / i f . . . i f . . . 但并不总是能够处理正确. 想达到两个效果:注释能够缩进,注释的内容不进行处理。还没有好的解决办法. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#118/34 对齐 仔细选择的对齐可以让代码更容易阅读. v a r ( v a r ( x , y i n t = 2 , 3 / /

15、 f o o x , y i n t = 2 , 3 / / f o o z f l o a t 3 2 / / b a r = = z f l o a t 3 2 / / b a r s s t r i n g / / b a l s s t r i n g / / b a l ) ) 很难进行手工维护 (制表符并不能够做到). 但是却非常适合使用格式化工具. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#119/34 灵活的制表符宽度 通常的制表符把当前的写位置移动到下一个固定的位置. 基本的办法:让制表符宽度更加灵活.

16、 制表符可以标示一个文本单元的结束位置. 一个列块是一个连续的相邻的单元. 一个列块的宽度可以到达多个单元里最宽文本的宽度. 被 Nick Gravgaard 提出于2006 (http:/ 实现在 t e x t / t a b w r i t e r 包中. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#120/34 灵活制表符宽度的展示 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#121/34 综合在一起 (1) 分析器生成 AST. 打印工具递

17、归地打印AST,使用制表符去灵活的标示制表符的位置. 产生的词汇,位置和空格流会和注释流进行合并. 词汇会扩展为字符串,所有的文本流将会被制表符写入器处理. 制表符写入器会将制表符替换为合适数量的空格. 对于固定宽度的字体,处理的很好. 比例大小的字体也可以被编辑器支持,如果这个编辑器可以支持灵活的制表符宽度. 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#122/34 综合在一起 (2) 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#123/34 从宏观

18、上看 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#124/34 gofmt 的应用 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#125/34 gofmt 作为源代码变换工具 改写 Go 的代码 (Russ Cox), g o f m t - r g o f m t - w - r a i : l e n ( x ) - a i : * . g o 简化 Go 的代码, g o f m t - s 更新 API (Russ Cox), g o f i x

19、 改变语言 (去掉分号,其它) goimport (Brad Fitzpatrick) 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#126/34 大家的反应 Go 项目要求所有提交的源代码都用 gofmt 的格式。 一开始,大家都抱怨:gofmt 不知道怎样格式成我的风格! 慢慢地,大家不作声了:Go 项目组一定要用 gofmt! 最后,大家看清了:gofmt 不是任何人的风格,但所有人都喜欢 gofmt 的风格。 现在,大家都赞扬: g o f m t 是大家喜欢 Go 的一个原因。 现在,格式已经不是一个问题。 4/2

20、1/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#127/34 其它语言也在向我们学习 Google 的 BUILD 文件现在也有格式器 (Russ Cox). Java 格式器 Clang 格式器 Dartfmt www.dartlang.org/tools/dartfmt/ (https:/www.dartlang.org/tools/dartfmt/) 等等 现在,任何语言都被要求带有自动的源代码格式器。 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#128/

21、34 总结 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#129/34 编程文化的演变 g o m f t 是 Go 语言的一个重要的卖点 大家渐渐达成共识:一致的“足够好“的格式很有好处 这种在 AST-级别上的源代码操作带动了一系列的新的工具。 其它语言也在向我们学习:编程的文化在慢慢演变。 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#130/34 至今的收获:应用程序 一开始,基本的源代码格式化是一个很好的目标。 但是,真正的用处在于源代码的变换工

22、具。 不要给大家有选择格式的机会。 越简单越好。 我们想要: Go 分析器:源代码 = 语法树 尽可能让语法树的操作变得容易。 Go 打印器:语法树 = 源代码 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#131/34 至今的收获:实现过程 最初的版本有很多的尝试和失败。 最大的错误:注释没有连到 AST-节点上. = 现在的设计使得操作 AST 和保持注释在正确的地方十分困难。 很混乱:ast.CommentMap 我们想要: 容易操作语法树,连带注释。 4/21/2015 gofmt 的文化演变 http:/127.0

23、.0.1:3999/gofmt-cn.slide#132/34 将来的计划 正在设计新的语法树(仍在试验阶段) 语法树操作起来更加简单和容易(例如:声明结点) 更快和更容易地使用分析器和打印器。 让工具用起来可靠并且快。其它一概不理。 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#133/34 Thank you Robert Griesemer Google, Inc. grigolang.org (mailto:grigolang.org) 4/21/2015 gofmt 的文化演变 http:/127.0.0.1:3999/gofmt-cn.slide#134/34

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/环境 > 装饰装潢


经营许可证编号:宁ICP备18001539号-1