cmd/go, x/tools/gopls: clarify error messages about std modules (which have no '.')

ldfqzlk8  于 6个月前  发布在  Go
关注(0)|答案(6)|浏览(52)

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 文件以匹配实际触发此问题的用例,并简化了期望描述。

epfja78i

epfja78i1#

我认为cmd/go可能按预期工作,我们之前曾声明,所有第一个组件中没有点的名字都被认为是为标准库保留的。

7uzetpgm

7uzetpgm2#

在VSCode中打开快速修复建议时,gopls或Go扩展建议获取package notstd/proto,这是没有意义的。对于没有点号的包,建议go get是没有意义的,因为它们保证不会被go get获取。但要澄清的是,对于以模块路径为前缀的包go get,情况并非完全没有意义,因为该包可能位于嵌套模块中。话虽如此,这种情况在99%以上的情况下并不会出现,我们可以更好地诊断实际问题。

cu6pst1q

cu6pst1q3#

当go命令失败时,它是否可以额外报告go.mod文件是否包含"module foo",其中foo不包含'.'且不是"std"?@bcmills@matloob
此外,也许gopls可以有一个检查器来报告这种形式的模块声明,这样一旦犯错就可以立即学习到'.'规则。(更新:@findleyr告诉我,不幸的是,市面上有很多这样的模块:它们作为主模块工作得很好,尽管它们无法获取。也许在gopls错误消息中添加一个提示会更好。)

z2acfund

z2acfund5#

让我为我们的用例添加一些更多的上下文...我真的很喜欢我可以做以下事情来为我们的学习课程,其中 dat520 是课程代码:

module dat520

事实上,整个要点是主仓库不应该被获取,因为它是私有的,并且包含比我们与学生共享的更多的代码。我们将主仓库的一部分复制到另一个每年的仓库中,例如,dat520-2024(也是私有的),从学生那里拉入他们自己的私有仓库。导入路径变得很短是一件好事。但更重要的是,没有人会困惑地认为他们需要 go get 某个仓库,而这个仓库对他们来说是不可达的,我们也不必重写导入以匹配学生的仓库路径。
我真的希望我们能继续使用我们当前的方法,并且“没有点的模块名是保留的”这个想法永远不会被强制执行。我宁愿处理一个不太理想的错误信息(现在我们知道它了,所以很容易检测到),也不愿意失去使用像 dat520 这样模块名的能力。我们已经经历了从 GOPATH 到模块的糟糕的几年过渡。

sshcrbum

sshcrbum6#

感谢您的上下文。我同意,这种用法似乎相当合理,无论如何我们不能禁止以前合法的行为。正如我在后记中指出的那样,也许我们能做的最好的事情是在go命令因某些错误而退出时添加一个额外的提示。

相关问题