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

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

Create generic struct that implements substructs

问题

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

type Item struct {
    payload Payload
}

type Payload struct {
    Name string
}

type SubscriptionPayload struct {
    subscriptionId string
    payload
}

type ResourcePayload struct {
    resourceId string
    payload
}

我的目标是,我希望能够生成的项中,有效载荷包含有效载荷结构的公共属性和特定属性。例如:
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.

type Item struct {
payload Payload
}

type Payload struct {
Name: String
}

type SubscriptionPayload struct {
subscriptionId string
payload
}

type ResourcePayload struct{
resourceId string 
payload
}

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

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

type Item struct {
	Payload Payload
}

type Payload struct {
	Name string
	*SubscriptionPayload
	*ResourcePayload
}

type SubscriptionPayload struct {
	SubscriptionId string
}

type ResourcePayload struct{
	ResourceId string
}

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

type QuotaType interface {
	Quota | []any
}

type Quota struct {
	Limit      uint64
}

type GeneralQuota[T QuotaInterface] struct {
	Id         string
	Bytes      *T
	Keys       *T
}

func main() {
	var q Quota
	var gq GeneralQuota[Quota]
	gq.Keys = &q
}

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

英文:

i think y want something there, its classic

type Item struct {
	Payload Payload
}

type Payload struct {
	Name string
	*SubscriptionPayload
	*ResourcePayload
}

type SubscriptionPayload struct {
	SubscriptionId string
}

type ResourcePayload struct{
	ResourceId string
}

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


type QuotaType interface {
	Quota | []any
}

type Quota struct {
	Limit      uint64

}

type GeneralQuota[T QuotaInterface] struct {
	Id         string
	Bytes      *T
	Keys       *T
}

func main() {
	var q Quota
	var gq GeneralQuota[Quota]
	gq.Keys = &q
}

and previosly coment about ifaces good and work too

答案2

得分: 0

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

type Item struct {
    Payload IPayload
}

type IPayload interface {
    GetName() string
}

type Payload struct {
    Name string
}

func (p *Payload) GetName() string { return p.Name }

type SubscriptionPayload struct {
    SubscriptionId string
    Payload
}

type ResourcePayload struct {
    ResourceId string
    Payload
}

《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.

type Item struct {
	Payload IPayload
}

type IPayload interface {
	GetName() string
}

type Payload struct {
	Name string
}

func (p *Payload) GetName() string { return p.Name }

type SubscriptionPayload struct {
	SubscriptionId string
	Payload
}

type ResourcePayload struct {
	ResourceId string
	Payload
}

A Tour of Go

答案3

得分: 0

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

type Payloader interface {
	GetPayloadName() string
}

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

package main

import "fmt"

func main() {
	var item Item

	item = Item{
		payload: &SubscriptionPayload{
			subscriptionId: "1234",
			Payload: Payload{
				Name: "subscription1",
			},
		},
	}
	fmt.Println(item.payload.GetPayloadName())
	if subsPayl, ok := item.payload.(*SubscriptionPayload); ok {
		fmt.Println(subsPayl.subscriptionId)
	}

	item = Item{
		payload: &ResourcePayload{
			resourceId: "5678",
			Payload: Payload{
				Name: "resource1",
			},
		},
	}
	fmt.Println(item.payload.GetPayloadName())
	if subsPayl, ok := item.payload.(*ResourcePayload); ok {
		fmt.Println(subsPayl.resourceId)
	}
}

type Item struct {
	payload Payloader
}

type Payload struct {
	Name string
}

func (p *Payload) GetPayloadName() string {
	return p.Name
}

type SubscriptionPayload struct {
	subscriptionId string
	Payload
}

type ResourcePayload struct {
	resourceId string
	Payload
}

type Payloader interface {
	GetPayloadName() string
}

由于类型是基于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.

type Payloader interface {
	GetPayloadName() string
}

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.

package main

import "fmt"

func main() {
	var item Item

	item = Item{
		payload: &SubscriptionPayload{
			subscriptionId: "1234",
			Payload: Payload{
				Name: "subscription1",
			},
		},
	}
	fmt.Println(item.payload.GetPayloadName())
	if subsPayl, ok := item.payload.(*SubscriptionPayload); ok {
		fmt.Println(subsPayl.subscriptionId)
	}

	item = Item{
		payload: &ResourcePayload{
			resourceId: "5678",
			Payload: Payload{
				Name: "resource1",
			},
		},
	}
	fmt.Println(item.payload.GetPayloadName())
	if subsPayl, ok := item.payload.(*ResourcePayload); ok {
		fmt.Println(subsPayl.resourceId)
	}
}

type Item struct {
	payload Payloader
}

type Payload struct {
	Name string
}

func (p *Payload) GetPayloadName() string {
	return p.Name
}

type SubscriptionPayload struct {
	subscriptionId string
	Payload
}

type ResourcePayload struct {
	resourceId string
	Payload
}

type Payloader interface {
	GetPayloadName() string
}

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:

确定