You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用Decodable解析同一JSON内不同容器的数据

没问题!复用同一个Weather结构体来解析不同位置的JSON数据完全可行,核心就是针对不同的JSON路径做数据提取,然后映射到同一个结构体上。我给你分几种常见语言的场景来举例,你可以对应自己用的语言参考:

解决方案:复用Weather结构体解析不同JSON路径

核心思路

不管JSON数据在哪个容器里,只要字段结构匹配,就能用同一个结构体来解析。关键是定位到目标数据所在的JSON节点,再把节点数据反序列化到Weather结构体即可。

示例代码(Go语言)

假设你的JSON结构长这样:

{
  "currently": {
    "temp": 22.5,
    "humidity": 0.6,
    "summary": "Partly Cloudy"
  },
  "daily": {
    "data": [
      {
        "temp": 25.0,
        "humidity": 0.5,
        "summary": "Sunny"
      },
      {
        "temp": 23.0,
        "humidity": 0.7,
        "summary": "Cloudy"
      }
    ]
  }
}

首先定义你的Weather结构体(和你现有解析currently的一样):

type Weather struct {
    Temp     float64 `json:"temp"`
    Humidity float64 `json:"humidity"`
    Summary  string  `json:"summary"`
}

然后解析不同位置的数据:

package main

import (
    "encoding/json"
    "fmt"
)

// 上面的Weather结构体定义在这里

func main() {
    jsonData := []byte(`{"currently": {"temp":22.5,"humidity":0.6,"summary":"Partly Cloudy"},"daily":{"data":[{"temp":25.0,"humidity":0.5,"summary":"Sunny"},{"temp":23.0,"humidity":0.7,"summary":"Cloudy"}]}}`)

    // 方式1:先解析整个JSON到临时结构,定位目标节点
    var rawData map[string]interface{}
    if err := json.Unmarshal(jsonData, &rawData); err != nil {
        panic(err)
    }

    // 解析currently容器的Weather对象
    currentlyBytes, _ := json.Marshal(rawData["currently"])
    var currentWeather Weather
    json.Unmarshal(currentlyBytes, &currentWeather)
    fmt.Println("当前天气:", currentWeather)

    // 解析daily->data里的多个Weather对象
    dailyData := rawData["daily"].(map[string]interface{})["data"].([]interface{})
    var dailyWeathers []Weather
    for _, item := range dailyData {
        itemBytes, _ := json.Marshal(item)
        var w Weather
        json.Unmarshal(itemBytes, &w)
        dailyWeathers = append(dailyWeathers, w)
    }
    fmt.Println("每日天气:", dailyWeathers)

    // 方式2:定义顶层结构体,一次性解析更优雅
    type WeatherResponse struct {
        Currently Weather   `json:"currently"`
        Daily     DailyData `json:"daily"`
    }
    type DailyData struct {
        Data []Weather `json:"data"`
    }

    var resp WeatherResponse
    json.Unmarshal(jsonData, &resp)
    fmt.Println("优雅版当前天气:", resp.Currently)
    fmt.Println("优雅版每日天气:", resp.Daily.Data)
}

示例代码(Python语言)

用dataclasses和json模块实现,代码更简洁:

import json
from dataclasses import dataclass
from typing import List

@dataclass
class Weather:
    temp: float
    humidity: float
    summary: str

json_str = '''{"currently": {"temp":22.5,"humidity":0.6,"summary":"Partly Cloudy"},"daily":{"data":[{"temp":25.0,"humidity":0.5,"summary":"Sunny"},{"temp":23.0,"humidity":0.7,"summary":"Cloudy"}]}}'''
data = json.loads(json_str)

# 解析currently的Weather对象
current_weather = Weather(**data["currently"])
print("当前天气:", current_weather)

# 解析daily->data的多个Weather对象
daily_weathers = [Weather(**item) for item in data["daily"]["data"]]
print("每日天气:", daily_weathers)

关键要点

  • 确保Weather结构体的字段和JSON中目标对象的字段完全匹配(包括键名、数据类型),如果键名不一致可以用结构体标签(比如Go的json:"xxx",Python可以自定义字段映射)。
  • 不需要为不同位置的数据重新定义结构体,只要定位到对应的JSON节点,把节点数据反序列化到同一个Weather结构体即可。
  • 强类型语言推荐用顶层结构体的方式解析,代码更易维护;动态类型语言直接提取节点后映射即可。

内容的提问来源于stack exchange,提问作者Angus.M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:23:54