允许一个变量成为任何嵌入另一个结构体的结构体吗?

huangapple go评论79阅读模式
英文:

allow a variable to be any struct which embeds another struct?

问题

我正在编写一个应用程序,需要能够在不同的消息传递方法之间进行选择,比如Kafka或RabbitMQ。当应用程序启动时,它将使用一些配置变量来确定需要使用哪种类型的消息传递,并相应地进行实例化。为了尽可能简化,我尝试设置一个带有一些公共字段的struct,然后将其嵌入到我的实现的各个struct中。

然而,如果我这样做,然后尝试在我将某些东西声明为“父级”的“子级”struct中使用它,我会得到类型错误。

有没有办法实现我想要的效果?

type Messenger struct {
  msgOut chan string
  errOut chan string
}

type KafkaMessenger struct {
  Messenger
  client *kafka.Client
}

type RabbitMessenger struct {
  Messenger
  client *rmq.Client
}

func NewKafkaMessenger(outChan chan string, errChan chan error) *KafkaMessenger {
 // 创建一个新的 Kafka Messenger
}

func NewRabbitMessenger(outChan chan string, errChan chan error) *RabbitMessenger {
 // 创建一个新的 Rabbit Messenger
}

type Env struct {
  Messenger
}

func main() {
  env := Env{}
  msgType := os.Getenv("MESSAGE_TYPE")
  
  // 这个代码块失败,因为两种方法都没有生成严格的 'Messenger' 类型
  if msgType == "KAFKA" {
    env.Messenger = NewKafkaMessenger(...)
  } else {
    env.Messenger = NewRabbitMessenger(...)
  }
}

所以我的问题是,如果我想要存储输出

英文:

I'm writing an app that needs to be able to choose between different message passing methods, like Kafka or RabbitMQ. When the app starts up, it will use some config variable to determine which type of message passing it needs to use, and instantiate it accordingly. To keep things as easy as possible, I'm trying to set up a struct with some common fields, and then embedding that into the individual structs for my implementations.

However, if I do that, and then try to use the "child" structs where I've declared something as the "parent," I get type errors.

Is there a way to do what I'm aiming for?

type Messenger struct {
  msgOut chan string
  errOut chan string
}

type KafkaMessenger struct {
  Messenger
  client *kafka.Client
}

type RabbitMessenger struct {
  Messenger
  client *rmq.Client
}

func NewKafkaMessenger(outChan chan string, errChan chan error) *KafkaMessenger {
 // create a new kafka messenger
}

func NewRabbitMessenger(outChan chan string, errChan chan error) *RabbitMessenger {
 // create a new rabbit messenger
}

type Env struct {
  Messenger
}

func main() {
  env := Env{}
  msgType := os.Getenv("MESSAGE_TYPE")
  
  // This block fails because neither method produces a strict 'Messenger' type
  if msgType == 'KAFKA' {
    env.Messenger = NewKafkaMessenger(...)
  } else {
    env.Messenger = NewRabbitMessenger(...)
  }
}


So my question is this - if I want to store the output

答案1

得分: 2

使用一个接口:

type MessengerImpl struct {
  msgOut chan string
  errOut chan string
}

func (m MessengerImpl) Out() chan string {return m.msgOut}
func (m MessengerImpl) Err() chan string {return m.errOut}

type Messenger interface {
  Out() chan string
  Err() chan string
}

type KafkaMessenger struct {
  MessengerImpl
  client *kafka.Client
}

type Env struct {
  Messenger
}

当你嵌入 MessengerImpl 时,嵌入的结构体将实现 Messenger 接口,因此你可以将它传递给需要 Messenger 的地方。

英文:

Use an interface:

type MessengerImpl struct {
  msgOut chan string
  errOut chan string
}

func (m MessengerImpl) Out() chan string {return m.msgOut}
func (m MessengerImpl) Err() chan string {return m.errOut}

type Messenger interface {
  Out() chan string
  Err() chan string
}

type KafkaMessenger struct {
  MessengerImpl
  client *kafka.Client
}

type Env struct {
  Messenger
}

When you embed the MessengerImpl, the embedding struct will implement the Messenger interface, and thus you can pass it to places that require a Messenger.

huangapple
  • 本文由 发表于 2023年2月28日 08:04:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75586719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定