V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
smile561607154
V2EX  ›  Go 编程语言

有没有人来实现一下这个功能

  •  
  •   smile561607154 · 318 天前 · 2840 次点击
    这是一个创建于 318 天前的主题,其中的信息可能已经有所发展或是发生改变。
    {
    	"server1":{
        	"domain":"https://www.baidu.com",
             "api":{
             	"api1":"/api1"
             }
        },
        "server2":{
        	"domain":"https://www.google.com",
             "api":{
             	"api2":"/api2"
             }
        }
    }
    

    有这么一段 json ,想解析之后实现如下要求的功能

    1. 在使用 api1 或 api2 成员变量时,想着能在内部实现拼接上对应的 server1 或 server2 中的domain,如server1.api.api1得到的完整路径是: https://www.baidu.com/api1

    2. 达到 1 的目的就是不允许server1.domain和和server2.api.api2拼接

    3. 不想让调用者进做拼接工作

    4. 不想让调用者传入字符串作为参数

    最终的目的就是尽可能的获取到完整的正确的路径,避免随便拼接。

    如果不会 golang 的,可以使用其他语言实现,主要是看有没有什么好思路

    14 条回复    2023-06-15 14:49:25 +08:00
    xiadd
        1
    xiadd  
       318 天前
    这个直接问 chatgpt 好了
    swordfairy
        2
    swordfairy  
       318 天前
    gpt 回答,看是否有用
    -----------
    可以使用 Go 内置的 encoding/json 包将 JSON 解析成一个结构体。以下是一个 Go 示例代码:

    package main

    import (
    "encoding/json"
    "fmt"
    )

    // JSON 对应的结构体
    type Config struct {
    Server1 struct {
    Domain string `json:"domain"`
    Api struct {
    Api1 string `json:"api1"`
    } `json:"api"`
    } `json:"server1"`
    Server2 struct {
    Domain string `json:"domain"`
    Api struct {
    Api2 string `json:"api2"`
    } `json:"api"`
    } `json:"server2"`
    }

    // Api 类型封装了 server 的信息和 API 的路径
    type Api struct {
    baseURL string
    path string
    }

    // NewApi 方法创建一个 Api 对象
    func NewApi(config *Config, serverName string, apiName string) *Api {
    api := &Api{}

    switch serverName {
    case "server1":
    api.baseURL = config.Server1.Domain
    switch apiName {
    case "api1":
    api.path = config.Server1.Api.Api1
    default:
    panic(fmt.Sprintf("unsupported API: %s", apiName))
    }
    case "server2":
    api.baseURL = config.Server2.Domain
    switch apiName {
    case "api2":
    api.path = config.Server2.Api.Api2
    default:
    panic(fmt.Sprintf("unsupported API: %s", apiName))
    }
    default:
    panic(fmt.Sprintf("unsupported server: %s", serverName))
    }

    return api
    }

    // URL 方法返回拼接过的完整 URL
    func (api *Api) URL() string {
    return api.baseURL + api.path
    }

    func main() {
    // 假设这是从 HTTP 响应体中获取的 JSON 数据
    jsonStr := `
    {
    "server1": {
    "domain": "https://www.baidu.com",
    "api": {
    "api1": "/api1"
    }
    },
    "server2": {
    "domain": "https://www.google.com",
    "api": {
    "api2": "/api2"
    }
    }
    }
    `

    // 将 JSON 解析成结构体
    var config Config
    err := json.Unmarshal([]byte(jsonStr), &config)
    if err != nil {
    panic(err)
    }

    // 创建 API 对象并输出 URL
    api1 := NewApi(&config, "server1", "api1")
    fmt.Println(api1.URL()) // 输出 https://www.baidu.com/api1

    api2 := NewApi(&config, "server2", "api2")
    fmt.Println(api2.URL()) // 输出 https://www.google.com/api2
    }
    -----------
    smile561607154
        3
    smile561607154  
    OP
       318 天前
    @swordfairy 当然是问过 gpt 了,这个实现之后,调用的时候需要传入字符串当作参数了。容易传错的可能
    swordfairy
        4
    swordfairy  
       318 天前
    Maboroshii
        5
    Maboroshii  
       318 天前
    第一步用 map[string]interface{} 解析这个 json , 然后遍历一遍所有的 $.server{x}.api.api{x} 把这些值都修改一次,加上 domain ,然后再给外部调用
    raysonlu
        6
    raysonlu  
       318 天前
    思路无非是重构一个 kv 结构:"api"=>"domain"
    8355
        7
    8355  
       318 天前
    其实思路是以 api 为主对象进行封装
    domain 是 api 对象的一个成员属性
    不给伪代码了 自己思考一下吧。。。
    lesismal
        8
    lesismal  
       318 天前   ❤️ 10
    怎么着,这年头伸手党都这么犀利了吗?又不是什么复杂的难题,要是说“请教下怎么实现”那都绝对不算是伸手党。可这连标题都是下需求,OP 头像脸都不要了也就算了,咋请教个问题也脸都不要了呢。。

    是因为经济不景气、所以楼上各位就这么卷着来伺候伸手党吗?建议不要吧

    早上起床气还没有散,加上是 go 的,希望 gopher 至少能动动脑子,所以对不住了各位,请收了神通吧!
    zengzizhao
        9
    zengzizhao  
       318 天前   ❤️ 1
    @lesismal 正在奇怪,刷新一下看到你发的,那我就不发了😅
    NessajCN
        10
    NessajCN  
       318 天前
    两个问题:
    一、"server1"和"server2"这样的键名是怎么获取的?你不想传入字符串的意思是,这俩是 hardcode 进去而不是变量?
    二、你这 json 能改吗?
    {
    "server1":{
    "domain":"https://www.baidu.com",
    "api":{
    "api1":"/api1"
    }
    },
    "server2":{
    "domain":"https://www.google.com",
    "api":{
    "api2":"/api2"
    }
    }
    =>
    {
    [
    {
    "servername":"server1",
    "domain":"https://www.baidu.com",
    "api":{
    "api1":"/api1"
    }
    },
    {
    "servername":"server2",
    "domain":"https://www.google.com",
    "api":{
    "api2":"/api2"
    }
    }
    ]
    }
    弄成这样的 ok 不?
    bv
        11
    bv  
       318 天前
    1. 问题描述的不够清晰,至少我个人觉得读了几遍不是很理解。
    2. 这个 JSON 用例看起来设计的不够直观。
    3. 基于我的理解,写了一个 demo 不知道是不是你期望的结果: https://goplay.tools/snippet/5BiXw_xKxcw
    smile561607154
        12
    smile561607154  
    OP
       318 天前
    @bv 很厉害,从你的示例中学到了很多东西,JSON 结构是可以改变的
    soar0712
        13
    soar0712  
       317 天前   ❤️ 1
    @lesismal 哈哈,犀利的,直接的
    smile561607154
        14
    smile561607154  
    OP
       317 天前
    感谢大家的回复,我从

    @bv
    @NessajCN
    @swordfairy 各位的建议中获取了思路,最终达到了我想要的。

    这是 demo 代码片段: https://goplay.tools/snippet/-1XgF5N8y61
    如果有更好的方案,可以再讨论讨论。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   949 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:35 · PVG 03:35 · LAX 12:35 · JFK 15:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.