英文:
Poisoning A Package/Function in GO
问题
TLDR:在golang中是否有一种方法(即使有点非标准),可以“毒化”某个函数或整个包的导入。
较长版本:我正在编写一个thrift服务,其中所有公共函数都返回在thrift文件中声明的某种类型的结果或错误。代码生成器为接口生成的代码如下所示:
publicFacingFunc(...) (returnType, error)
这很好,直到我与之合作的某个人决定检查另一个条件,并且当条件不满足时执行以下操作:
if conditionIsNotMet {
return nil, errors.New(...)
}
代码可以编译,但当错误发生时,接收到的消息是未记录的随机字符串。因此,在这些文件中,我希望阻止使用“errors”和“fmt”包。
是的,我尝试过,在文件顶部仍然有一个明显的警告,但似乎没有人读。
顺便说一下,所有公共错误都有相应的“构造函数”,这些函数是外部的,只应使用这些函数,在我的情况下。
英文:
TLDR: Is there a way in golang (even if it is a bit non-standard), to "poison" a function or import of a certain package altogether.
The longer version: I am writing a thrift service, which all public facing functions return results, or an error of a certain type, declared in the thrift file. The code generator generates code for the interface like this:
publicFacingFunc(...) (returnType, error)
This would be great, until someone I am working with decides to check for another condition, and when that condition is not met does something like this:
if conditionIsNotMet {
return nil, errors.New(...)
}
The code compiles, but when the error arises, the received message is undocumented random string. So in these files, I want to prevent usage of "errors" and "fmt" packages.
And yes, I tried, and still have I a blaring warning at the top of the file, but nobody seems to read.
BTW, the public errors all have a respective "constructor", which is external to these files, and only those should be used, in my case.
答案1
得分: 0
如果你只关心一个文件中的包的使用,你可以使用一个愚蠢的名称来导入它,比如'NEVER'...然后人们可以使用它,但他们会明白这个意思。
import (
NEVER "fmt"
)
或者,如果你想更加正式一些,你可以使用下划线 _
,https://golang.org/doc/effective_go.html#blank_import
import (
_ "fmt"
)
这将加载导入包,但只会产生它的副作用(也就是说,不会被显式使用)。
要停止所有不属于某种特定类型的错误输入,你可以使用reflect
来使用类型断言停止不需要的类型,https://golang.org/ref/spec#Type_assertions
v, ok = x.(T)
所以,如果在公共的函数中出现了一个你不想传递的err
,可以检查它是什么类型的错误,
specialError, ok := err.(mypackage.ErrorType)
if !ok {
// 不要传递这个错误
}
英文:
If you're only concerned with a packages use within a file, you could import it under a silly name, like 'NEVER'... and people could use it, but they'd get the idea I think.
import (
NEVER "fmt"
)
OR, if you want to be less silly, you could use the _
underscore, https://golang.org/doc/effective_go.html#blank_import
import (
_ "fmt"
)
which will load the import, but only it's side effects (that is, not for explicit use.
<hr>
To stop the input of all errors not of a certain type, you could use reflect
in order to stop the undesirable types with type assertion, https://golang.org/ref/spec#Type_assertions
v, ok = x.(T)
So if an err
comes up in the public facing function, that you don't want passed through, check what kind of error it is,
specialError, ok := err.(mypackage.ErrorType)
if !ok {
// don't send this error on
}
答案2
得分: 0
如果你真的想强制执行这个规定,你可以在构建过程中使用一个步骤来检查所有包的go list
输出,并确保fmt
和errors
不在直接导入列表中。不过,由于这些是常用的包,完全避免可能会有困难。你可以进行更详细的解析以检测fmt.Errorf
或其他情况,但可能会比较棘手。
一种更具侵入性的解决方案是修改这些包的源代码,并强制开发人员使用你定制的Go发行版。对于在标准库中几乎无处不在的fmt
和errors
包来说,这可能太难以实现了,但对于其他包可能有效。不过,我绝不推荐这样做。你可以将其作为构建时的验证步骤,用于检查提交和Pull Request等操作。
英文:
If you really want to enforce it, you could do a build step that checks the output of go list
for all of your packages, and make sure fmt
and errors
are not in the list of direct imports. With such common packages though, it could be difficult to avoid altogether. You could do more detailed parsing to detect fmt.Errorf
or whatever, but could be tricky.
A more invasive solution would be modifying package source for those packages and forcing devs to use your custom go distribution. Probably too hard to pull off for the fmt
and errors
packages that are used literally everywhere in the std lib, but it may work for other packages. I would never recommend it though. Definitely add it as a build-time validation that runs on checkins and PRs and things.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论