gofmt 的文化演变
The Cultural Evolution of gofmt
Robert Griesemer
Google, Inc.
Robert Griesemer
Google, Inc.
GRINDEF (Bill Gosper, 1967) 第一个计算行长度
SOAP (R. Scowen et al, 1969) 简化了晦涩的算法程序 NEATER2 (Ken Conrow, R. Smith, 1970) PL/1格式器,作为(早期的)纠错工具 cb (Unix Version 7, 1979) C程序美化器 indent (4.2 BSD, 1983) 缩进和格化化C代码 等等
ClangFormat C/C++/Objective-C 格式器 Uncrustify C, C++, C#, ObjectiveC, D, Java, Pawn and VALA的美化器 等等
一个格化标准搞定所有!
8// Syntax of an if statement. IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] . // An IfStmt node represents an if statement. IfStmt struct { If token.Pos // position of "if" keyword Init Stmt // initialization statement; or nil Cond Expr // condition Body *BlockStmt Else Stmt // else branch; or nil }
case *ast.IfStmt: p.print(token.IF) p.controlClause(false, s.Init, s.Cond, nil) p.block(s.Body, 1) if s.Else != nil { p.print(blank, token.ELSE, blank) switch s.Else.(type) { case *ast.BlockStmt, *ast.IfStmt: p.stmt(s.Else, nextIsRBrace) default: p.print(token.LBRACE, indent, formfeed) p.stmt(s.Else, true) p.print(unindent, formfeed, token.RBRACE) } }
p.print
)接收包括位置和空格符等的一系列记号x = a + b x = a + b*c if a+b <= d { if a+b*c <= d {
// A CommentGroup represents a sequence of comments // with no other tokens and no empty lines between. // type CommentGroup struct { List []*Comment // len(List) > 0 }
func f() { func() { /* /* * foo * foo * bar ==> * bar * bal * bal */ */ if ... if ... } }
var ( var ( x, y int = 2, 3 // foo x, y int = 2, 3 // foo z float32 // bar ==> z float32 // bar s string // bal s string // bal ) )
通常的制表符把当前的写位置移动到下一个固定的位置.
基本的办法:让制表符宽度更加灵活.
被 Nick Gravgaard 提出于2006
nickgravgaard.com/elastic-tabstops/
实现在 text/tabwriter
包中.
对于固定宽度的字体,处理的很好.
比例大小的字体也可以被编辑器支持,如果这个编辑器可以支持灵活的制表符宽度.
21gofmt -r
gofmt -w -r 'a[i:len(x)] -> a[i:]' *.go
gofmt -s
go fix
gofmt
不知道怎样格式成我的风格!gofmt
是大家喜欢 Go 的一个原因。现在,格式已经不是一个问题。
26www.dartlang.org/tools/dartfmt/
现在,任何语言都被要求带有自动的源代码格式器。
27gofmt
是 Go 语言的一个重要的卖点我们想要:
=> 现在的设计使得操作 AST 和保持注释在正确的地方十分困难。
我们想要: