你正在使用的Go版本是什么( go version
)?
$ go version
go version devel +5aef51a729 Sun Mar 29 02:01:34 2020 +0000 linux/amd64
这个问题在最新版本中是否会重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/myitcv/.cache/go-build"
GOENV="/home/myitcv/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/myitcv/gostuff"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/myitcv/gos"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/myitcv/gos/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build136829961=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
不清楚这是设计还是不是,所以提出来以便完整。以下测试在我预期它会通过时失败了:
# Test demonstrating the sensitivity of bracket placement
# for require directives
exec go mod tidy
cmp go.mod go.mod.golden
-- go.mod --
module mod.com
go 1.12
require()
-- go.mod.golden --
module mod.com
go 1.12
相比之下,Go工具链对带空格的括号内的通用声明关键字是否有空格不敏感。
你期望看到什么?
通过测试
你实际看到了什么?
# Test demonstrating the sensitivity of bracket placement
# for require directives (0.004s)
> exec go mod tidy
[stderr]
go: errors parsing go.mod:
$WORK/go.mod:5: unknown directive: require()
cc @bcmills@jayconrod@matloob
2条答案
按热度按时间xxls0lw81#
我已经研究了这个问题 #24031 。在大多数情况下,
go.mod
解析器只是根据空格来分割标记。因此,replace()
是一个标记。但是请注意,如果(
或)
是空格后的第一个字符,它总是被解释为与紧跟其后的非空白字符分开的一个单独的标记(因此require ()more
是四个标记,而不是两个)。我认为一般地更改这种标记化是不安全的:ASCII括号字符(
( ) [ ] { }
)不允许出现在模块路径中,但它们都允许出现在replace
指令右侧的文件路径中。它们也允许出现在未解决的版本中。因此,如果(
在一系列非空白字符中间被词法分析为一个单独的标记,它可能会破坏一些go.mod
文件,这些文件是go
命令的较新版本。无论如何,在进行这样的更改之后,旧版本的go
命令将无法接受使用这种语法编写的go.mod
文件。yjghlzjz2#
https://golang.org/cl/226639提到了这个问题:
modfile: scan ASCII brackets and commas as separate tokens