ZBLOG

还有别的实现吗

当然,还有其他几种实现方法可以解决你提到的问题,主要的思路是在反序列化时处理字符串格式的 JSON 数组。以下是几种替代方案:

1. 手动解析字符串

在获取 Redis 数据后,可以先将 ipv4Addresses 字段提取出来,然后手动解析这个字符串。

import (
    "encoding/json"
    "fmt"
)

// NfProfile 是包含网络功能实例信息的结构体
type NfProfile struct {
    NfInstanceId   string   `json:"nfInstanceId" yaml:"nfInstanceId" bson:"nfInstanceId" mapstructure:"NfInstanceId"`
    // ...其他字段...
    Ipv4Addresses  []string `json:"ipv4Addresses,omitempty"`
}

// 手动解析 JSON 字符串
func parseIPv4Addresses(data string) ([]string, error) {
    var addresses []string
    err := json.Unmarshal([]byte(data), &addresses)
    return addresses, err
}

// 使用示例
func main() {
    modified := []byte(`{"nfInstanceId": "example", "ipv4Addresses": "[\"192.168.1.1\", \"10.0.0.1\"]"}`)
    
    var temp struct {
        NfInstanceId   string `json:"nfInstanceId"`
        Ipv4Addresses  string `json:"ipv4Addresses"` // 保存为字符串类型
    }

    if err := json.Unmarshal(modified, &temp); err != nil {
        fmt.Printf("Error unmarshalling data: %v\n", err)
        return
    }
    
    ipv4Addrs, err := parseIPv4Addresses(temp.Ipv4Addresses)
    if err != nil {
        fmt.Printf("Error parsing IPv4 addresses: %v\n", err)
        return
    }

    profile := NfProfile{
        NfInstanceId:  temp.NfInstanceId,
        Ipv4Addresses: ipv4Addrs,
    }

    fmt.Println(profile)
}

2. 使用接口和反射

如果不想修改原有结构体的字段类型,可以使用 interface{} 接收,并在之后进行判断和转换。这种方式虽然稍显复杂,但保持了原有结构体的完整性。

package models

import (
	"encoding/json"
	"fmt"
)

type NfProfile struct {
	NfInstanceId   string      `json:"nfInstanceId"`
	Ipv4Addresses  interface{} `json:"ipv4Addresses,omitempty"` // 用 interface{} 来接收任意数据类型
}

func (p *NfProfile) UnmarshalJSON(data []byte) error {
	type Alias NfProfile // 避免无限递归
	aux := &struct {
		Ipv4Addresses json.RawMessage `json:"ipv4Addresses"` // 暂存为 RawMessage 类型以便后续解析
		*Alias
	}{
		Alias: (*Alias)(p),
	}

	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}

	p.Ipv4Addresses = aux.Ipv4Addresses // 临时保存为 RawMessage

	var ipSlice []string 
	if len(aux.Ipv4Addresses) > 0 { 
	    if err := json.Unmarshal(aux.Ipv4Addresses, &ipSlice); err != nil { 
	        return fmt.Errorf("failed to unmarshal ipv4 addresses: %w", err)
	    }
	    p.Ipv4Addresses = ipSlice 
	} 

	return nil 
}

小结

这些方法各有优缺点,可以根据具体需求选择合适的方法。如果代码可读性和维护性更重要,那么第一种方法相对简单清晰;而第二种方法则提供了更大的灵活性,但可能导致一定的复杂度。在实际开发中,可以根据团队编码风格和项目要求来决定采用哪种方案。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=7113

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?