Go语言(golang)第一个正式版Go1发布了,但是这个新兴的编程语言还是非常不完善。这不,我(Liigo)又发现它的编译器竟然不支持编译带BOM的UTF-8编码的.go源文件。这就很奇怪,该语言明明要求源代码文件.go必须是UTF-8编码,但有不允许带UTF-8 BOM。要知道,这个世界上带BOM的文件太多了,很多文本编辑器/代码编辑器/IDE都会默认生成带有BOM的UTF-8文件。如果仅仅因为源代码文件多了BOM,编译器将不能编译这个文件,我觉得它太低能了。
Go语言编译器(gc)不支持带有BOM的UTF-8源文件:
Golang's compiler (gc) don't accept the .go files with UTF-8 BOM:
好在Go语言是开源项目,我(Liigo)来贡献代码,让它支持编译带UTF-8 BOM的.go源代码文件。经过分析后发现,Go语言编译器(gc)源代码中有两处地方涉及从磁盘文件中读取.go文件:一个是C语言写的词法分析器(src/cmd/gc/lex.c),一个是Go语言写的.go文件解析器(src/pkg/go/parser/interface.go)。解决思路也很简单,就是从磁盘读取文件内容后,判断前三个字节,与UTF-8 BOM的三个字节(0xef, 0xbb, 0xbf)核对,如果一致则忽略这三个字节,从第四个字节算作文件的真正内容,然后再交给词法分析器和解析器处理,后面就一切正常了。
Go语言的词法分析器是用C语言手工编写的,其中用到了lib9/libbio库,是一个磁盘文件读写缓冲区,逐字节读取该缓冲区时,它可以做到“反读取”最近的4个字节,就是说,假设我刚刚读取了abcd是个字节,现在我“反读取”后两个字节,实际上就相当于我刚刚读取了ab还没有读取cd。利用它的这个“凡读取”机制,恰恰可以很容易的忽略掉UTF-8文件最前面的BOM:首先读出前三个字节,如果这三个字节正好是UTF-8 BOM的三个字节(0xef, 0xbb, 0xbf),那么直接把刚刚读出的三个字节扔掉就完事了,后面词法分析器处理时正好从BOM后面的字节开始读取;如果已经读出的三个字节不是UTF-8
BOM呢,需要“反读取”,即把他们再放回去,就当作我没有读取过它们。修改后的代码如下:
Go语言的源代码解析器(pkg/go/parser)是用Go语言自己编写的,其功能是解析.go源代码文件为语法树。Go语言官方提供的go build命令用pkg/go/parser分析处理编译前的库依赖项。go build命令(pkg/go/parser)是把.go文件整个读入内存后再解析的。我要做的工作就是,在pkg/go/parser开始正式解析前,把前面可能存在的UTF-8 BOM删除掉即可,这个工作仅仅涉及Go语言中byte slice的基本操作,是很轻量级的廉价操作。
我把上面修改的代码提交到Go语言官方源码库,代码审查页面地址是:
http://codereview.appspot.com/6036054/, 或http://codereview.appsp0t.com/6036054/。
但是Go语言的作者/官方开发者拒绝这一改进。Go开发组老大Rob Pike亲自回复给出就拒绝的理由:
在我看来,理由非常勉强,在逻辑上甚至都不成立。哦,既然规定了.go必须使用UTF-8编码,所以就一定不能加UTF-8 BOM了?加了BOM就拒不接收了?前面已经说过了,很多文本编辑器都会自动添加UTF-8 BOM的,怎么到你这里就不合法了。一个很现实的例子是,Windows XP / Windows 7系统内置的“记事本”程序(notepad.exe)在保存UTF-8文件时是一定会自动添加UTF-8 BOM的。也就是说,你想用记事本保存的.go源代码是一定不能编译通过的。但就是这么严重的问题,Go作者们就是不当一回事;这么容易就可以改进的问题,他们就是拒绝改进。生生的为用户使用go语言又凭空制造一道阻力。要说是面临技术方案的妥协选择折中还可以理解,偏偏要在无关紧要的地方坚持己见宁死不去考虑方便用户。我只能说他们是死脑筋。类似的情况我遇到也不止一次了,总结下来就是:技术大牛挂帅做产品害人害己;闭门造车的代价是死都不知道咋死的。(这样的总结也为我们做易语言产品敲响了警钟:绝对不能单纯以技术人员的心态做产品。)
分享到:
相关推荐
Golang编译器是将Go语言编写的源代码转换成机器码的工具,它遵循了严格的语言规范,并提供了一系列编译优化功能。源代码阅读是一个深入理解编译器内部工作原理的有效方法,对于开发者来说,这不仅有助于提升编程技能...
UTF-8的特殊之处在于它包含一个字节顺序标记(BOM),即UTF-8+BOM,但大多数情况下,UTF-8无BOM更常见。 在PHP中,进行字符编码转换可以使用内置函数,如`mb_convert_encoding()`,这个函数可以将字符串从一种编码...
标题"Go语言项目UTF-8文件转ANSI编码源代码+dos执行文件"表明,这是一个使用Go语言编写的程序,它的功能是将使用UTF-8编码的文本文件转换为ANSI编码。在Windows系统中,ANSI通常指的是系统默认的本地代码页,例如GBK...
Go语言的编译器是其生态系统的关键组成部分,它负责将源代码转换为可执行的机器码。对于Windows 64位系统,你需要的是"windows-amd64"架构的编译器。"go1.9.windows-amd64.msi"就是这个平台的编译器安装包。 3. **...
5. **转换为结构化数据**:将解析后的NMEA数据转化为Go语言中的结构体或地图,便于进一步处理和分析。 6. **错误处理**:在解析过程中,可能会遇到无效的NMEA数据或格式错误。库应提供适当的错误处理机制,帮助...
1. **纯Golang实现**:Go-Snapshot完全使用Golang编写,充分利用了Go语言的并发模型和内存管理机制,确保了系统的高并发性和内存安全性。 2. **KV存储模型**:该系统采用了键值对的存储方式,用户可以通过Key进行...
首先,它引入了Go Modules的支持,这使得Go语言的依赖管理和模块化开发更加方便。其次,它还改进了垃圾回收机制,提高了程序的性能。此外,v1.23.2版本还对网络编程、并发编程等做了优化,使得开发者在编写高性能...
在Go语言中,虽然它自身不直接支持GBK编码,但是可以通过第三方包如mahonia来实现GBK和UTF-8之间的转换。mahonia是一个Go语言实现的字符编码转换库,它能够帮助开发者处理GBK、Big5、GB2312等多种中文字符集与...
【标题】"Go-go-ole-golang的Win32OLE实现"主要涉及到的是在Go语言中如何使用`go-ole`库来实现Windows操作系统上的Win32对象链接与嵌入(OLE)技术。OLE是微软在Windows平台上实现的一个组件对象模型(COM),它允许...
Go语言,又称Golang,是由Google开发的一种静态类型的、编译型的、并发型且具有垃圾回收功能的编程语言。其设计目标是提高开发效率,简化多并发编程,并提供强大的工具链支持。在Go语言的开发环境中,选择合适的编辑...
go-admin是一个基于golang的快速搭建可视化数据管理后台的框架。它具有以下特点: 1. 高生产效率: 使用go-admin,您可以在短短10分钟内创建一个漂亮的管理后台。这大大提高了开发效率,让您能够更快地完成项目。 2. ...
对于**Go语言(Golang)** 开发者而言,它能提供强大的语法高亮、代码跳转和语义分析等功能,帮助开发者更深入地理解和探索Go代码。 本资源是"source insight的golang语言支持包",专为Source Insight设计,使得这...
标题中的“gcc-golang-mingw64-9.0.rar”表明这是一个针对Windows系统(因为有“mingw64”标识)的压缩包,它包含了用于编译Go语言程序的GCC(GNU Compiler Collection)环境。这个环境是Golang在Windows上运行时,...
Go语言,又称为Golang,是由Google设计的一种开放源代码的编程语言。它具备高效性、简洁性和易用性的特点,在现代软件开发领域备受青睐。以下是Go语言的一些关键特性: 1. **快速编译**: Go语言能在几秒钟内编译...
在本文中,我们将深入探讨如何使用Golang(Go语言)来构建一个基于LDAP(轻量级目录访问协议)的Web应用程序。LDAP是一种用于存储和检索用户、组织和资源信息的标准,广泛应用于身份验证和授权系统。Go语言由于其...
它支持面向对象编程的特性,但并没有采用传统的类继承机制,而是引入了接口的概念,使得Go语言的类型系统更加灵活和简洁。此外,Go语言还内置了并发支持,它通过goroutines提供了一种轻量级的线程,允许开发者以更...
Golang 数据可视化利器 go-echarts 监控 Oracle Database 在本文中,我们将探讨如何使用 Golang 和 go-echarts 库来监控 Oracle Database,实现数据可视化。下面是相关知识点: 1. go-echarts 库简介 go-echarts ...
Go-go.vm项目是一个基于Golang语言实现的简单虚拟机,它旨在为开发者提供一个学习和理解虚拟机、编译器和解释器工作原理的平台。本文将深入探讨该项目中的关键概念和技术细节。 首先,我们要了解什么是虚拟机。...
1. **Go语言 (Go/Golang)**:Go是由Google开发的一种静态类型的、编译型的、垃圾回收的、并发型的、具有C风格语法的编程语言。Go语言强调代码简洁和效率,特别适合构建网络服务和系统工具。 2. **MIPS架构**:MIPS...
weixin-golang-sdk 微信golang工具包