Go版本
go版本 devel go1.22-33d4a51 darwin/arm64
在你的模块/工作区中的go env
输出:
Not relevant. It isn't a bug per se, but a request for better error messages.
你做了什么?
go.mod
:
module notstd
go 1.22
server/server.go
:
package main
import "notstd/proto"
func Insert(req *proto.InsertRequest) (*proto.InsertResponse, error) {
return &proto.InsertResponse{Success: true}, nil
}
在 proto
文件夹中没有Go文件(暂时):
├── go.mod
├── proto
│ └── kv.proto
└── server
└── server.go
你看到了什么?
$ go run ./server/
server/server.go:4:2: package notstd/proto is not in std (/Users/meling/sdk/gotip/src/notstd/proto)
$ gopls check server/server.go
/Users/meling/tmp/notstd/server/server.go:4:2-16: could not import notstd/proto (no required module provides package "notstd/proto")
当在VSCode中打开快速修复建议时, gopls
或Go扩展建议 go get package notstd/proto
,这是没有意义的。
你期望看到什么?
我期望编译器和gopls报告在同一模块的 proto
文件夹中没有Go文件,因为导入是明确地尝试导入其自己的包。
对于简单的示例,可能很容易弄清楚你忘记了编译proto文件以填充 proto
包。但在大型项目中,可能会很容易忘记,学生不一定理解问题所在,如果他们被要求自己编译proto文件。此外,这种情况下的错误信息也没有帮助。
编辑:添加了 kv.proto
文件以匹配实际触发此问题的用例,并简化了期望描述。
6条答案
按热度按时间epfja78i1#
我认为cmd/go可能按预期工作,我们之前曾声明,所有第一个组件中没有点的名字都被认为是为标准库保留的。
7uzetpgm2#
在VSCode中打开快速修复建议时,gopls或Go扩展建议获取package notstd/proto,这是没有意义的。对于没有点号的包,建议
go get
是没有意义的,因为它们保证不会被go get获取。但要澄清的是,对于以模块路径为前缀的包go get
,情况并非完全没有意义,因为该包可能位于嵌套模块中。话虽如此,这种情况在99%以上的情况下并不会出现,我们可以更好地诊断实际问题。cu6pst1q3#
当go命令失败时,它是否可以额外报告go.mod文件是否包含"module foo",其中foo不包含'.'且不是"std"?@bcmills@matloob
此外,也许gopls可以有一个检查器来报告这种形式的模块声明,这样一旦犯错就可以立即学习到'.'规则。(更新:@findleyr告诉我,不幸的是,市面上有很多这样的模块:它们作为主模块工作得很好,尽管它们无法获取。也许在gopls错误消息中添加一个提示会更好。)
2vuwiymt4#
这让我想起,我需要清理 https://go.dev/cl/359594 并将其合并。😩
z2acfund5#
让我为我们的用例添加一些更多的上下文...我真的很喜欢我可以做以下事情来为我们的学习课程,其中
dat520
是课程代码:事实上,整个要点是主仓库不应该被获取,因为它是私有的,并且包含比我们与学生共享的更多的代码。我们将主仓库的一部分复制到另一个每年的仓库中,例如,
dat520-2024
(也是私有的),从学生那里拉入他们自己的私有仓库。导入路径变得很短是一件好事。但更重要的是,没有人会困惑地认为他们需要go get
某个仓库,而这个仓库对他们来说是不可达的,我们也不必重写导入以匹配学生的仓库路径。我真的希望我们能继续使用我们当前的方法,并且“没有点的模块名是保留的”这个想法永远不会被强制执行。我宁愿处理一个不太理想的错误信息(现在我们知道它了,所以很容易检测到),也不愿意失去使用像
dat520
这样模块名的能力。我们已经经历了从 GOPATH 到模块的糟糕的几年过渡。sshcrbum6#
感谢您的上下文。我同意,这种用法似乎相当合理,无论如何我们不能禁止以前合法的行为。正如我在后记中指出的那样,也许我们能做的最好的事情是在go命令因某些错误而退出时添加一个额外的提示。