Go 是否可以使用较大结构项的子集作为函数的参数(映射到较小结构)?
假设我有以下结构Go 是否可以使用较大结构项的子集作为函数的参数(映射到较小结构)?,go,Go,假设我有以下结构 package foobar type Foo struct{} type Bar struct{} func (*Bar) Read(p []byte) (n int, err error) { return 0, nil } 在我的应用程序中的某个地方,我打算使用这样的结构之一 package consumer type DoOptions struct { bar io.Reader } func Do(opts *DoOptions) {
package foobar
type Foo struct{}
type Bar struct{}
func (*Bar) Read(p []byte) (n int, err error) {
return 0, nil
}
在我的应用程序中的某个地方,我打算使用这样的结构之一
package consumer
type DoOptions struct {
bar io.Reader
}
func Do(opts *DoOptions) {
fmt.Println(opts)
}
我的目标是拥有一个通用的依赖容器,并让客户机规定他们希望从中获取哪些依赖
package main
type dependencyContainer struct {
foo *Foo
bar *Bar
}
func main() {
s := &dependencyContainer{
foo: &foobar.Foo{},
bar: &foobar.Bar{},
}
consumer.Do(s)
}
但这当然不起作用:
cannot use s (variable of type *dependencyContainer) as *DoOptions value in argument to consumer
我有没有办法做到这一点
看看其他的选择,他们都很讨厌
接口中只能有方法
context意味着大量不必要的强制转换,函数的API变得混乱
具有多个函数参数可能是高维护,因为导入顺序很重要,并且在您向下钻取依赖关系图中的属性时会重复
我有没有办法做到这一点
不需要。重新设计。您想要的与图案非常相似。请记住,函数是Go中的一级公民,因此您可以使用apply方法通过函数或函子-结构传递数据 例如:
package main
import "fmt"
type do struct{}
type DoOption func(*do)
func Do(opts ...DoOption) {
do := do{}
for _, opt := range opts {
opt(&do)
} // "apply" the options
// use the values...
}
type Foo struct{ value string }
type Bar struct{ value string }
func WithFoo(x Foo) func(*do) {
return func(*do) { fmt.Println(x.value) }
}
func WithBar(x Bar) func(*do) {
return func(*do) { fmt.Println(x.value) }
}
type dependencyContainer struct {
foo Foo
bar Bar
}
func main() {
s := dependencyContainer{Foo{"foo"}, Bar{"bar"}}
Do(WithFoo(s.foo), WithBar(s.bar))
}
此外,许多人认为,显式依赖项注入(即通过构造函数公开所有依赖项,而不是将它们隐藏在使用者的代码中)会产生更好的可维护代码。您是否考虑过将依赖项容器传递给Do方法,让每个使用者明确地从容器中选择他们的依赖项?@mkopriva问题是,我希望使用者像库一样不知道它的环境上下文。虽然使用结构作为参数不如参数标准,但它仍然比硬编码orchestrator的依赖关系上下文更抽象。如果需要向使用者隐藏不相关的依赖关系,并且与orchestrator的初始设计非常接近,我唯一能想到的就是使用接口。接口仅为行为而没有数据的限制,即没有字段可以通过getter来克服。例如:虽然我同意您的观点,但目标是通过构造函数显式地注入所有依赖项。使用对象作为参数保留了优点,并确保依赖顺序无关紧要。