如何从在golang中导入的包中接收到的结构体中删除特定的项?

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

How to remove certain items from a struct received from an imported package in golang?

问题

我正在从一个导入的第三方模块的包中接收一个项目:

myItem := importedPackage.get()

它是这样的一个结构体:

type ImportedStruct struct {
    Ip                  net.IP                  `json:"ip"`
    Index               uint32                  `json:"index"`
    LocalIndex          uint32                  `json:"localIndex"`
    RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
    Certificates        *certificates           `json:"certificates"`
    VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
}

在将其作为JSON从我的Golang Gin API返回之前,我想删除其中的一个或多个项目:

c.JSON(200, &myItem)

问题在于如何找到最节省资源的方法来实现这一点。

我考虑过使用循环将我需要的字段写入一个新的结构体:

newItem := make([]ImportedStruct, len(myItem))

i := 0
for _, v := range myItem {
    newItem[i] = ...
    ...
}

c.JSON(200, &newItem)

我还考虑过将其编组然后解组以将其分配给另一个结构体,然后通过API返回:

// 将主机映射编组为JSON
marshaledJson, err := json.Marshal(newItem)
if err != nil {
    log.Error(err)
    c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
    return
}

// 将JSON解组为结构体
var unmarshalledJson []ImportedStruct
err = json.Unmarshal(marshaledJson, &unmarshalledJson)
if err != nil {
    log.Error(err)
    c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
    return
}

// 返回修改后的主机映射
c.JSON(200, &unmarshalledJson)

但我希望能找到更高效的方法来实现这一点。myItem可能包含超过3百万行的JSON,遍历所有行,或者编组和解组似乎涉及了比实现相对简单的目标所需的更多的过程。

编辑:该结构体是一个切片([])。

英文:

I am receiving an item from a package of an imported third-party module:

myItem := importedPackage.get()

It is a struct like this:

type ImportedStruct struct {
    Ip                  net.IP                  `json:"ip"`
    Index               uint32                  `json:"index"`
    LocalIndex          uint32                  `json:"localIndex"`
    RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
    Certificates        *certificates           `json:"certificates"`
    VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
}

I would like to remove one or more of the items there, before returning it from my Golang Gin API as JSON:

c.JSON(200, &myItem)

The issue is trying to find the most resource efficient way to do this.

I have considered a loop and writing the fields I need to a new struct:

newItem := make([]ImportedStruct, len(myItem))

i := 0
for _, v := range myItem {
    newItem[i] = ...
    ...
}

c.JSON(200, &hostList)

I also considered marshalling and then unmarshalling to assign it to another struct before returning it through the API:

// Marshal the host map to json
marshaledJson, err := json.Marshal(newItem)
if err != nil {
	log.Error(err)
	c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
	return
}

// Unmarshal the json into structs
var unmarshalledJson []ImportedStruct
err = json.Unmarshal(marshaledJson, &unmarshalledJson)
if err != nil {
	log.Error(err)
	c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
	return
}

// Return the modified host map
c.JSON(200, &unmarshalledJson)

I'm hoping though to find a more efficient way to do this. myItem could contain over 3m lines of JSON, and looping through it all, or marshalling and unmarshalling seems like it involves more processes then it needs just to achieve something relatively simple.

Edit: The struct is a slice ([]).

答案1

得分: 3

定义一个新的结构体,它是现有结构体的副本,但具有不同的标签:

type ImportedStructMarshal struct {
    Ip                  net.IP                  `json:"ip"`
    Index               uint32                  `json:"index"`
    LocalIndex          uint32                  `json:"-"`
    RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
    Certificates        *certificates           `json:"certificates"`
    VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
}

然后,使用这个新的结构体进行编组:

var input ImportedStruct
forMarshal := ImportedStructMarshal(input)
...

只要新的结构体与导入的结构体在字段上是兼容的,这将起作用。

英文:

Define a new struct that is a copy of the one you have, with different tags:

type ImportedStructMarshal struct {
    Ip                  net.IP                  `json:"ip"`
    Index               uint32                  `json:"index"`
    LocalIndex          uint32                  `json:"-"`
    RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
    Certificates        *certificates           `json:"certificates"`
    VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
}

Then, use this new struct to marshal:

var input ImportedStruct
forMarshal:=ImportedStructMarshal(input)
...

This will work as long as the new struct is field-by-field compatible with the imported struct.

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

发表评论

匿名网友

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

确定