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

330 天前
 smile561607154
{
	"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 的,可以使用其他语言实现,主要是看有没有什么好思路

2852 次点击
所在节点    Go 编程语言
14 条回复
xiadd
330 天前
这个直接问 chatgpt 好了
swordfairy
330 天前
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
330 天前
@swordfairy 当然是问过 gpt 了,这个实现之后,调用的时候需要传入字符串当作参数了。容易传错的可能
swordfairy
330 天前
Maboroshii
330 天前
第一步用 map[string]interface{} 解析这个 json , 然后遍历一遍所有的 $.server{x}.api.api{x} 把这些值都修改一次,加上 domain ,然后再给外部调用
raysonlu
330 天前
思路无非是重构一个 kv 结构:"api"=>"domain"
8355
330 天前
其实思路是以 api 为主对象进行封装
domain 是 api 对象的一个成员属性
不给伪代码了 自己思考一下吧。。。
lesismal
330 天前
怎么着,这年头伸手党都这么犀利了吗?又不是什么复杂的难题,要是说“请教下怎么实现”那都绝对不算是伸手党。可这连标题都是下需求,OP 头像脸都不要了也就算了,咋请教个问题也脸都不要了呢。。

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

早上起床气还没有散,加上是 go 的,希望 gopher 至少能动动脑子,所以对不住了各位,请收了神通吧!
zengzizhao
330 天前
@lesismal 正在奇怪,刷新一下看到你发的,那我就不发了😅
NessajCN
330 天前
两个问题:
一、"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
330 天前
1. 问题描述的不够清晰,至少我个人觉得读了几遍不是很理解。
2. 这个 JSON 用例看起来设计的不够直观。
3. 基于我的理解,写了一个 demo 不知道是不是你期望的结果: https://goplay.tools/snippet/5BiXw_xKxcw
smile561607154
330 天前
@bv 很厉害,从你的示例中学到了很多东西,JSON 结构是可以改变的
soar0712
329 天前
@lesismal 哈哈,犀利的,直接的
smile561607154
329 天前
感谢大家的回复,我从

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

这是 demo 代码片段: https://goplay.tools/snippet/-1XgF5N8y61
如果有更好的方案,可以再讨论讨论。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/948558

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX