英文:
Create constants visible across packages, accessible directly
问题
我想在一个名为models
的包中定义我的错误代码
。
error.go
package models
const{
EOK = iota
EFAILED
}
我如何在另一个包中使用它们,而不必将它们引用为models.EOK
?我希望可以直接使用EOK
,因为这些代码将在所有包中通用。
这样做是正确的方式吗?有更好的替代方案吗?
英文:
I would like to define my Error Codes
in a package models
.
error.go
package models
const{
EOK = iota
EFAILED
}
How can I use them in another package without referring to them as models.EOK
. I would like to use directly as EOK, since these codes would be common across all packages.
Is it the right way to do it? Any better alternatives?
答案1
得分: 11
回答你的核心问题
你可以使用dot
导入语法将另一个包中导出的符号直接导入到你的包的命名空间中(godoc):
import . "models"
这样,你就可以直接引用EOK
常量,而不需要在前面加上models
前缀。
**然而,我强烈建议不要这样做,因为它会生成难以阅读的代码。**请参考下面的示例。
一般/风格建议
- 不要使用未加前缀的导入路径,比如
models
。这被认为是不好的风格,因为它很容易造成命名冲突。即使是用于内部使用的小项目,也应该使用类似myname/models
的形式。参考goblog。 - 关于你关于错误生成的问题,有一些用于生成
error
值的函数,比如errors.New
(godoc)和fmt.Errorf
(godoc)。
关于Go语言和错误处理的一般介绍,请参考goblog。
英文:
To answer you core question
You can use the dot
import syntax to import the exported symbols from another package directly into your package's namespace (godoc):
import . "models"
This way you could directly refer to the EOK
constant without prefixing it with models
.
However I'd strongly advice against doing so, as it generates rather unreadable code. see below
General/style advice
- Don't use unprefixed export path like
models
. This is considered bad style as it will easily globber. Even for small projects, that are used only internally, use something likemyname/models
. see goblog - Regarding your question about error generation, there are functions for generating
error
values, e.g.errors.New
(godoc) andfmt.Errorf
(godoc).
For a general introduction on go and error handling see goblog
答案2
得分: 1
关于初始问题,可以选择一个简洁的包名,例如 err。
选择传播错误和生成错误消息的方法取决于应用程序的规模和复杂性。你展示的错误样式,使用一个整数,然后使用一个函数进行解码,这种方式相当于 C 语言的风格。
这种风格部分是由于以下原因造成的:
- 缺乏多值返回(不像 Go 语言),
- 需要使用简单类型(以便于传播),
- 并且使用函数将其转换为文本(不像 Go 语言的错误接口),以便可以更改本地语言字符串。
对于简单错误字符串的小型应用程序,我将包的错误字符串放在包文件的开头,然后直接返回它们,可能使用 errors.New(...) 或者 fmt.Errorf(如果字符串需要使用一些数据进行补充)。
那种“int”风格的错误报告并没有提供像 Go 语言的错误接口那样灵活的功能。错误接口允许我们构建信息丰富的错误结构,返回有用的信息,而不仅仅是一个整数值或字符串。
一个影响是不同的包可以产生实现 Error 接口的不同的实际类型。我们不需要在整个包集合中达成一致的单一错误实际类型。因此,错误是一个可以很容易传播的接口,就像一个整数,然而,错误的实际类型可以比整数更丰富。错误生成(实现 Error)可以根据需要集中或分散,而不像 strerror() 风格的函数那样难以扩展。
英文:
W.r.t. the initial question, use a compact package name, for example err.
Choosing an approach to propagating errors, and generating error messages depends on the scale and complexity of the application. The error style you show, using an int, and then a function to decode it, is quite C-ish.
That style was partly caused by:
- the lack of multiple value returns (unlike Go),
- the need to use a simple type (to be easily propagated), and
- that gets translated to text with a function (unlike Go's error interface), so that the local language strings can be changed.
For small apps with simple errors strings. I put the packages' error strings at the head of a package file, and just return them, maybe using errors.New(...), or fmt.Errorf if the string needs to be completed using some data.
That 'int' style of error reporting doesn't offer something as flexible as Go's error interface. The error interface lets us build information-rich error structures, to return useful information, and not just an int value or string.
An implication is different packages can yield different real-types which implement the Error interface. We don't need to agree a single error real-type across an entire set of packages. So error is an interface which can be easily propagated, like an int, yet, the real-type of error can be much richer than an int. Error generation (implementing Error) can be as centralised or distributed as we need, unlike strerror()-style functions which can be awkward to extend.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论