我们有 2 个实现相同函数签名的包。在我的主要任务中,我需要根据条件切换正在使用的包:
import (
packageA "deployment/sdk/packageA"
packageB "deployment/sdk/packageB"
)
someCondition := true
var packageToUse ?
if someCondition {
packageToUse = packageA
} else {
packageToUse = packageB
}
packageToUse.DoSomething()
当然,这不会编译。我不知道 packageToUse 使用什么类型。这种方法可能是一种反模式。我只是不确定我应该采取的方法。
有什么建议吗?
我得到的错误是use of package without selector
最佳答案
除了动态导入之外,这在很大程度上是一种模式。它叫做„Interfaces“ .
给定一个接口(interface)定义
type Stringer interface{
String() string
}
和实现所述接口(interface)的类型 Foo
type foo int
func(f foo)String() string{
return fmt.Sprintf(”%d”,f)
}
以及实现所述接口(interface)的 Bar
type bar string
func (b bar) String()string {
return string(b)
}
实际上可以将两者都用作函数 baz 的参数
func baz(s Stringer){
fmt.Println(s.String())
}
请注意,与其他语言不同,您不必声明类型实现的接口(interface)——只要类型碰巧实际实现了接口(interface),go 编译器就可以接受。 Run on Playground
所以,关于你的包导入问题:除非你有巨大的依赖树要导入,否则真的不值得这么麻烦。
假设我们讨论了一个使用 BBolt 或 etcd 的应用程序,以及一些 MongoDB。包括所有 在内的最终大小虽然相对来说相当惊人,但可以忽略不计。我用 bbolt、bbolt & etcd 和 bbolt、etcd & mongodb 的导入编译了一个 go 程序。这些是以字节为单位的结果。
11734884 size_all
2455544 size_bolt
10307700 size_boltetcd
我们说的是几兆字节的文件大小。所以假设您使用 Bolt 或 etcd 或 MongoDB,您是否真的想跳过完成动态导入所需的所有循环适本地?就我而言,我既不想这样做,也不希望 Go 提供这样的功能。
"Premature optimization is the root of all evil (or at least most of it) in programming."
– Donald Knuth
关于根据条件去包选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56811922/