为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以使用较大结构项目的子集作为函数的参数(映射到较小的结构)?

是否可以使用较大结构项目的子集作为函数的参数(映射到较小的结构)?

Go
UYOU 2022-05-23 17:25:27
说我有以下结构package foobartype Foo struct{}type Bar struct{}func (*Bar) Read(p []byte) (n int, err error) {     return 0, nil }在我的应用程序的某个地方,我打算像这样使用这些结构之一package consumertype DoOptions struct {    bar io.Reader}func Do(opts *DoOptions) {    fmt.Println(opts)}我的目标是拥有一个通用的依赖容器,并让客户规定他们希望从中获取哪些依赖。package maintype 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.Context意味着大量不必要的强制转换,并且函数的 API 变得混乱当您在依赖关系图中钻取属性时,拥有多个函数参数可以通过导入顺序和重复进行高度维护
查看完整描述

2 回答

?
慕的地10843

TA贡献1785条经验 获得超8个赞

您想要的看起来与功能选项模式非常相似。请记住,函数是 Go 中的一等公民,因此您可以通过函数(或struct带有 " 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))

}

https://play.golang.org/p/48rCTwn1f9C


此外,许多人认为显式依赖注入(即通过构造函数公开所有依赖项,而不是将它们隐藏在消费者代码中)会导致更好的可维护代码。


查看完整回答
反对 回复 2022-05-23
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

我有什么办法可以做到这一点吗?

不,重新设计。


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信