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

如何在Go语言中解析JSON数据并输出为清晰文本格式

嘿,这个需求实现起来超简单的!我给你两种实用的方法,你可以根据自己的场景来选:

方法一:定义结构体解析后格式化输出(推荐,类型安全)

这种方法是先把ipinfo.io返回的JSON结构映射成Go的结构体,然后直接提取字段拼接成你要的文本格式,优点是类型安全,不容易出错,适合需要固定输出字段的场景。

首先定义和接口返回对应的结构体:

type IPInfo struct {
    IP       string `json:"ip"`
    City     string `json:"city"`
    Region   string `json:"region"`
    Country  string `json:"country"`
    Loc      string `json:"loc"` // 经纬度信息
    Org      string `json:"org"` // 运营商/机构信息
    Postal   string `json:"postal"`
    Timezone string `json:"timezone"`
}

然后修改你的iplocation函数,解析JSON后格式化输出:

import (
    "encoding/json"
    "fmt"
    "net/http"
)

func ipLocation(ip string) error {
    // 构造请求URL
    reqURL := fmt.Sprintf("https://ipinfo.io/%s/json", ip)
    resp, err := http.Get(reqURL)
    if err != nil {
        return fmt.Errorf("请求ipinfo接口失败: %w", err)
    }
    defer resp.Body.Close()

    // 解析JSON到结构体
    var ipInfo IPInfo
    if err := json.NewDecoder(resp.Body).Decode(&ipInfo); err != nil {
        return fmt.Errorf("解析JSON失败: %w", err)
    }

    // 按照你想要的格式拼接输出文本
    result := fmt.Sprintf(
        "ip: %s, city: %s, region: %s, country: %s, location: %s, org: %s, postal: %s, timezone: %s",
        ipInfo.IP,
        ipInfo.City,
        ipInfo.Region,
        ipInfo.Country,
        ipInfo.Loc,
        ipInfo.Org,
        ipInfo.Postal,
        ipInfo.Timezone,
    )
    fmt.Println(result)
    return nil
}

如果担心某些字段为空(比如部分IP可能没有postal信息),还可以加个简单的空值处理,比如:

// 处理空字段,替换成"未知"
city := ipInfo.City
if city == "" {
    city = "未知"
}
// 然后在Sprintf里用city变量代替ipInfo.City
方法二:用Map解析(灵活,无需定义结构体)

如果你不想提前定义结构体,也可以直接把JSON解析成map[string]interface{},然后提取对应字段输出。这种方法更灵活,但要注意类型断言,避免panic:

func ipLocation(ip string) error {
    reqURL := fmt.Sprintf("https://ipinfo.io/%s/json", ip)
    resp, err := http.Get(reqURL)
    if err != nil {
        return fmt.Errorf("请求接口失败: %w", err)
    }
    defer resp.Body.Close()

    var ipInfo map[string]interface{}
    if err := json.NewDecoder(resp.Body).Decode(&ipInfo); err != nil {
        return fmt.Errorf("解析JSON失败: %w", err)
    }

    // 提取字段时做类型断言,避免类型不匹配panic
    ipStr, _ := ipInfo["ip"].(string)
    cityStr, _ := ipInfo["city"].(string)
    regionStr, _ := ipInfo["region"].(string)
    countryStr, _ := ipInfo["country"].(string)

    result := fmt.Sprintf("ip: %s, city: %s, region: %s, country: %s",
        ipStr, cityStr, regionStr, countryStr)
    fmt.Println(result)
    return nil
}

这里用_忽略了断言失败的错误,如果字段不存在或者类型不对,对应的变量会是空字符串,你也可以根据需要添加错误处理逻辑。

总的来说,第一种方法更推荐,因为类型安全,代码可读性也更高,适合大多数场景~

内容的提问来源于stack exchange,提问作者Inzamam Raja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:39:56