创建一个实现子结构的通用结构体。

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

Create generic struct that implements substructs

问题

我对golang还比较新,对于如何使其工作感到困惑。
我创建了一个包含一些子类型的通用结构,这些子类型以有效载荷的形式存在。

  1. type Item struct {
  2. payload Payload
  3. }
  4. type Payload struct {
  5. Name string
  6. }
  7. type SubscriptionPayload struct {
  8. subscriptionId string
  9. payload
  10. }
  11. type ResourcePayload struct {
  12. resourceId string
  13. payload
  14. }

我的目标是,我希望能够生成的项中,有效载荷包含有效载荷结构的公共属性和特定属性。例如:
item1 := {"payload": {"name": "subscription1", "subscriptionId": "1234"}}
item2 := {"payload": {"name": "resource1", "resourceId": "5678"}}

我认为通过将有效载荷作为子类型的属性传递,这将继承有效载荷属性,但是我的问题是,我无法直接将子类型作为项内部有效载荷的值传递。

英文:

Im a bit newer to golang and struggle to make this work.
I create a generic structure with some subtypes in form of payloads.

  1. type Item struct {
  2. payload Payload
  3. }
  4. type Payload struct {
  5. Name: String
  6. }
  7. type SubscriptionPayload struct {
  8. subscriptionId string
  9. payload
  10. }
  11. type ResourcePayload struct{
  12. resourceId string
  13. payload
  14. }

My goal would be that I can generate items where the payload contains both the common and specific attributes of the payload structs. So for example
item1 := {"payload": {"name": "subscription1", "subscriptionId": "1234}
item2 := {"payload": {"name": "resource1", "resourceId": "5678"}

I thought by passing the payload as an attribute in the subtype this would inherit the payload attributes, but then my problem is that I cant pass the subtype directly as a value for payload inside the item.

答案1

得分: 1

我认为你想要对这部分进行翻译,这是经典的代码。

  1. type Item struct {
  2. Payload Payload
  3. }
  4. type Payload struct {
  5. Name string
  6. *SubscriptionPayload
  7. *ResourcePayload
  8. }
  9. type SubscriptionPayload struct {
  10. SubscriptionId string
  11. }
  12. type ResourcePayload struct{
  13. ResourceId string
  14. }

或者你可能在询问约束结构,例如:(如果你是Go语言的新手,不建议使用)

  1. type QuotaType interface {
  2. Quota | []any
  3. }
  4. type Quota struct {
  5. Limit uint64
  6. }
  7. type GeneralQuota[T QuotaInterface] struct {
  8. Id string
  9. Bytes *T
  10. Keys *T
  11. }
  12. func main() {
  13. var q Quota
  14. var gq GeneralQuota[Quota]
  15. gq.Keys = &q
  16. }

之前还评论过接口很好用,也能正常工作。

英文:

i think y want something there, its classic

  1. type Item struct {
  2. Payload Payload
  3. }
  4. type Payload struct {
  5. Name string
  6. *SubscriptionPayload
  7. *ResourcePayload
  8. }
  9. type SubscriptionPayload struct {
  10. SubscriptionId string
  11. }
  12. type ResourcePayload struct{
  13. ResourceId string
  14. }

or y may asking of constraint struct, ex: (not recomended, if y new in go)

  1. type QuotaType interface {
  2. Quota | []any
  3. }
  4. type Quota struct {
  5. Limit uint64
  6. }
  7. type GeneralQuota[T QuotaInterface] struct {
  8. Id string
  9. Bytes *T
  10. Keys *T
  11. }
  12. func main() {
  13. var q Quota
  14. var gq GeneralQuota[Quota]
  15. gq.Keys = &q
  16. }

and previosly coment about ifaces good and work too

答案2

得分: 0

你可能想要使用接口!接口类型被定义为一组方法签名。接口类型的值可以持有任何实现这些方法的值。

  1. type Item struct {
  2. Payload IPayload
  3. }
  4. type IPayload interface {
  5. GetName() string
  6. }
  7. type Payload struct {
  8. Name string
  9. }
  10. func (p *Payload) GetName() string { return p.Name }
  11. type SubscriptionPayload struct {
  12. SubscriptionId string
  13. Payload
  14. }
  15. type ResourcePayload struct {
  16. ResourceId string
  17. Payload
  18. }

《Go语言之旅》

英文:

You may want to use interface instead! An interface type is defined as a set of method signatures. A value of interface type can hold any value that implements those methods.

  1. type Item struct {
  2. Payload IPayload
  3. }
  4. type IPayload interface {
  5. GetName() string
  6. }
  7. type Payload struct {
  8. Name string
  9. }
  10. func (p *Payload) GetName() string { return p.Name }
  11. type SubscriptionPayload struct {
  12. SubscriptionId string
  13. Payload
  14. }
  15. type ResourcePayload struct {
  16. ResourceId string
  17. Payload
  18. }

A Tour of Go

答案3

得分: 0

一种处理方法是为共同部分(即Payload结构体)定义一个接口。这个接口可以非常简单,如下所示,或者根据共同行为包含更多功能。

  1. type Payloader interface {
  2. GetPayloadName() string
  3. }

所有包含payload结构体的结构体都会自动获得接口实现。然后,由于每个Item.payload都实现了这个接口,你可以进行类型断言来获取具体类型。下面是你提供的示例的完整实现。

  1. package main
  2. import "fmt"
  3. func main() {
  4. var item Item
  5. item = Item{
  6. payload: &SubscriptionPayload{
  7. subscriptionId: "1234",
  8. Payload: Payload{
  9. Name: "subscription1",
  10. },
  11. },
  12. }
  13. fmt.Println(item.payload.GetPayloadName())
  14. if subsPayl, ok := item.payload.(*SubscriptionPayload); ok {
  15. fmt.Println(subsPayl.subscriptionId)
  16. }
  17. item = Item{
  18. payload: &ResourcePayload{
  19. resourceId: "5678",
  20. Payload: Payload{
  21. Name: "resource1",
  22. },
  23. },
  24. }
  25. fmt.Println(item.payload.GetPayloadName())
  26. if subsPayl, ok := item.payload.(*ResourcePayload); ok {
  27. fmt.Println(subsPayl.resourceId)
  28. }
  29. }
  30. type Item struct {
  31. payload Payloader
  32. }
  33. type Payload struct {
  34. Name string
  35. }
  36. func (p *Payload) GetPayloadName() string {
  37. return p.Name
  38. }
  39. type SubscriptionPayload struct {
  40. subscriptionId string
  41. Payload
  42. }
  43. type ResourcePayload struct {
  44. resourceId string
  45. Payload
  46. }
  47. type Payloader interface {
  48. GetPayloadName() string
  49. }

由于类型是基于Payload.Name定义的,并且我们可以使用Payloader接口获取这个值,你可以定义一个switch代码块根据Payload.Name执行适当的操作。

英文:

One way you can handle this is by defining an interface for the common part (i.e., the Payload struct). This interface can be as simple as the following or you can include more functionality based on the common behavior.

  1. type Payloader interface {
  2. GetPayloadName() string
  3. }

All your structs that include payload struct will automatically get the interface implementation. Then, since each Item.payload implements this interface, you can perform a type assertion to get the concrete type. Below is a complete implementation for the example you provided.

  1. package main
  2. import "fmt"
  3. func main() {
  4. var item Item
  5. item = Item{
  6. payload: &SubscriptionPayload{
  7. subscriptionId: "1234",
  8. Payload: Payload{
  9. Name: "subscription1",
  10. },
  11. },
  12. }
  13. fmt.Println(item.payload.GetPayloadName())
  14. if subsPayl, ok := item.payload.(*SubscriptionPayload); ok {
  15. fmt.Println(subsPayl.subscriptionId)
  16. }
  17. item = Item{
  18. payload: &ResourcePayload{
  19. resourceId: "5678",
  20. Payload: Payload{
  21. Name: "resource1",
  22. },
  23. },
  24. }
  25. fmt.Println(item.payload.GetPayloadName())
  26. if subsPayl, ok := item.payload.(*ResourcePayload); ok {
  27. fmt.Println(subsPayl.resourceId)
  28. }
  29. }
  30. type Item struct {
  31. payload Payloader
  32. }
  33. type Payload struct {
  34. Name string
  35. }
  36. func (p *Payload) GetPayloadName() string {
  37. return p.Name
  38. }
  39. type SubscriptionPayload struct {
  40. subscriptionId string
  41. Payload
  42. }
  43. type ResourcePayload struct {
  44. resourceId string
  45. Payload
  46. }
  47. type Payloader interface {
  48. GetPayloadName() string
  49. }

Since the type is defined based on the Payload.Name and we can get this value using the Payloader interface, you can define a switch code block to perform proper actions based on the Payload.Name.

huangapple
  • 本文由 发表于 2023年5月30日 20:52:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76365064.html
匿名

发表评论

匿名网友

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

确定