
就冲 golang 可以生成二进制单文件这一点,部署方便,想试试
拿 beego 练个手,用了它的 httplib 模块,其中, request 后有个直接将结果转换成 json 的,原文如下:
解析为 JSON 结构, req.ToJSON(&result) 方法
返回结构直接解析为 JSON 格式,解析到 result 对象中
我!以!为!这是和 py 的 json.loads()一样,心理窃喜,接下来……
我传了个 string ,没数据,传个空接口,没数据。。。。。
看了下源码,是直接调用的 json.Unmarshal(data, v),属于 golang 自带的库,可我一搜……
竟然发现,需要提前定义 json 的结构???而且字段首字母必须大写???不然还得声明???
WTF
beego 的 request 可以返回 string ,像 py 的 requests.get(url).text ,但是我不想这样,我想 json.loads(requests.get(url).text)
我就是想获取个 json 而已,能不能不要这么折腾人?
1 Allianzcortex Dec 29, 2016 Go 是静态语言,在解析 JSON 上是没有 Python 有优势的 |
2 phrack Dec 29, 2016 via Android 难道你第一门语言是 py 不是 c ` |
3 icedx Dec 29, 2016 其实就是一个入乡随俗的道理 顺便 Python 是鸭子类型 这是没有这个特性的语言比不了的 |
4 choury Dec 29, 2016 via Android 你是没用过 C , java 这些吧 |
5 scnace Dec 29, 2016 试试解析到 map 里面(嘿嘿嘿 |
6 TheCure Dec 29, 2016 simplejson |
7 defia Dec 29, 2016 可以 map[string]interface{}吧 |
8 gouchaoer Dec 29, 2016 via Android 静态语言里不如 rust |
9 nicevar Dec 29, 2016 哈哈,如果让你用 c 来处理 json 会不会上吊了 |
10 only0jac OP |
11 Tyanboot PRO 看 |
12 scnace Dec 30, 2016 就是不用`struct`的形式了 而是采用`map[string]interface{}`的形式呀。然后`Unmarshal`之后 map 的 key(string)就是 json 的 key map 的 value 就是 json 的 value 惹 。 但是 我还是建议解到 struct 的 代码可维护性会强很多(不要问我怎么知道的 |
13 Tyanboot PRO @Tyanboot 不好意思手抖按到回复了… 我觉得看库的实现吧 c#有个 NewtonJson 。也是需要先有个定义好的类来做载体,才能解析到定义好的类的实例上。也就是需要先声明 JSON 的字段格式。 但是 c++是有个 jsoncpp 的库,不需要定义 JSON 的格式,用起来要舒服不少。 |
14 messyidea Dec 30, 2016 |
15 limhiaoing Dec 30, 2016 via iPhone json 反序列化成 struct 难道不是很方便的功能吗,而且一般不会强制要求必须定义结构体。这个能力一般都是用反射来实现的,楼上说的 C++现阶段要实现并不容易,可能至少需要静态反射标准化后才能做到。 rust 之前用过一个 json 库也有这个特性,不知道是怎么实现的。 |
16 soli Dec 30, 2016 知足吧。 别说 JSON ,你用 C 拼个字符串试试。 |
17 eyp82 Dec 30, 2016 python 党笑而不语 |
18 reus Dec 30, 2016 定义一个结构体很麻烦吗? var data struct { // xxx } 定义变量的时候就可以定义 struct ,或者说 go 的 struct 可以是匿名的 在静态类型语言里, go 处理 json 是最方便的了,因为有 reflection 别用什么 map[string]interface{},处理嵌套的结构你就知道了 var data struct { List []struct{ Info struct { // xxx } } } 你用 map[string]interface{}试试?类型转换烦死你。 再说回来,想学 go 就直接学标准库,别像学 py 一样,上来就框架。 go 的标准库功能比 py 的强得多,根本不需要 beego 这种东西。 |
19 kkk330 Dec 30, 2016 - 函数签名是 json.Unmarshal(data []byte , v interface{}) - 也就是说 lz 你想简单点就直接 ```go data := []byte("{"a":"a", "b": 1}") var v interface{} json.Unmarshal(data , v) fmt.Println(v) ``` |
20 jsq2627 Dec 30, 2016 via iPhone @Tyanboot 你说的只是 newtonjson 的一种早期强类型用法。现在是可以反序列化成 dynamic 类型,或者 jtoken 类型配合 linq 很方便。 虽然我没用过 go 但我觉得一定存在一种不需要预先定义 schema 的使用方式的。 |
21 est Dec 30, 2016 map[interface{}]interface{} 大法好。 另外静态语言里搞一个 [1, "1", None, {1: 2, None: 0, 2: 3}] 好像是不可能实现的。。 |
24 orvice Dec 30, 2016 首字母大写是因为不大写 json 包就获取不到成员的值了。 |
25 orvice Dec 30, 2016 也不一定要定义结构体啦,也可以用 map[string]interface{} 但是类型转换会烦死人、。。 |
27 Reficul Dec 30, 2016 via Android 等到接手一个老项目,不知道传过来的 JSON 里面元素有哪些的时候,就能感叹动态一时爽的道理了 |
28 yegle Dec 30, 2016 @est 可以实现,就是麻烦一点。你需要用一个 struct 来 hold 所有可能的值(类似 C union ),然后自己写 marshal/unmarshal 。 |
29 vizee Dec 30, 2016 好的, 那就不用 |
30 ericls Dec 30, 2016 via iPhone 我喜欢了很多的语言 是不是不够上道 |
31 keysona Dec 30, 2016 更有有点吧。 看你是要性能还是轻松了。 大部分情况下我会选择轻松。 |
32 huodon Dec 30, 2016 via Android 底子太差。。。 |
34 jingniao Dec 30, 2016 via Android 静态偏底层的处理,意味着 python 隐藏的的一些细节, go 中你得自己来处理。 昨天学习 go ,重写一个 python 模块,代码量至少两倍。 |
35 assassinpig Dec 30, 2016 via Android Go 不适合 LZ |
36 MushishiXian Dec 30, 2016 .....这有啥好吐槽的,你怎么不说性能 |
37 only0jac OP @messyidea 感谢,这篇很详细,回去仔细看看 @limhiaoing 方便吗,如果返回的 json 有 100 个字段,难道我 struct 里也需要跟着定义 100 个吗(假设这 100 个字段都有用) |
38 only0jac OP |
39 jeffersonpig Dec 30, 2016 最不能忍的是 go 强制{}的对齐方式, WTF |
40 limhiaoing Dec 30, 2016 via iPhone @only0jac 你非要着眼于不方便的地方不用就是了! |
43 kingddc314 Dec 30, 2016 via Android 静态语言就这样,要习惯,至少 Go 还有反射。当初 C/C++拼装解析 JSON 那才是一个痛苦,只是后来的 C++11 特性才好一丁点 |
44 ry_wang Dec 30, 2016 不想定义结构体还想用着简单, https://github.com/tidwall/gjson 啊。 |
45 Immortal Dec 30, 2016 静态语言都这样,不知道吐槽点在哪里. 既然选择了静态语言 势必要牺牲一些便携性 多写两行代码 空间换时间 而且看标题我以为是来夸 go 的... |
46 pubby Dec 30, 2016 via Android 我猜应该有工具能输入复杂样本自动生成结构定义的 有些比较麻烦的地方是 type JobTime time.Time 必须自己实现一遍 Marshal/Unmarshal |
47 Citrus Dec 30, 2016 前几楼不要乱黑啊,虽然个人不喜欢 Java ,但是 Java 反序列化 Json 还真不需要定义啊,而且有很多方法。 1. 直接反序列化成 Map<String, String> ,最粗暴,但是对某些 Json 结构支持不好 2. 直接反序列化成 JSONObject ,完美方案 |
50 kkk330 Dec 30, 2016 |
51 mengzhuo Dec 30, 2016 首先,静态语言就是这样的…… 100 项可以用 go generate 自动生成,首字母大写可以用 type A struct { ST `json:"st"` } |
52 likexian Dec 30, 2016 |
53 mengzhuo Dec 30, 2016 而且不一定要定义完 result ,你需要什么数据,就定义什么好了 比如 { "A": 1, "B": 2, "C": "OK", } 你的处理函数只需要里面的 C 的话, type Result struct { C string json.RawMessage } 具体请看官方标准库, https://golang.org/pkg/encoding/json/#example_RawMessage |
55 sampeng Dec 30, 2016 我觉得这是是语言的哲学决定的。 golang 的开发者觉得,开发语言不能有歧义,如果是不需要定义结构体。真的,在项目里面看到各种 json 对象乱飞,都不知道哪来得时候就很痛苦。 定义结构体最大的好处是语言自文档化,光看代码就能了解整个逻辑。现在特别反感在代码里绕圈子的。简直是折磨 想想 golang 连方法重载这种特性都没有就能理解了。。 |
56 tairan2006 Dec 30, 2016 via Android 楼主你没写过静态语言么… 实际上可以用匿名 struct 的,不一定要预定义 |
57 dreamtrail Dec 30, 2016 其实静态语言也没那么可怕,你只要写一次,以后直接复制代码修改一下就行了,虽然还是比不上脚本但也不是想象的那么麻烦。 |
58 gamexg Dec 30, 2016 python 转 go go 的 json 也是可以不先定义结构,但是每次使用时的检查和转换烦死人,静态类型语言都有这个问题。 不过现在觉得这是一个好的特征,只用定义好结构,然后 json 解析到结构一次就能够确定 json 符合预期,之后就不用每个字段都检查一次了。 另外搜索 generate go struct from json ,直接有在线网站提供根据 json 自动生成 go 结构,直接用即可。 python 时就已经是动态一时爽,重构火葬场了。 每次接口修改字段都需要检查很多地方,悲剧的是 ide 搜索不是找到不相关的就是漏下一些。 静态语言 ide 可以轻松找出来哪些地方引用了接口的结构。 只要确定结构定义处改了,即使有忘了的地方编译时自动报错。 |
59 magicdawn Dec 30, 2016 C# 都有 dynamic |
62 ispinfx Dec 30, 2016 via iPhone 人生苦短 我用 Python |
63 moliliang Dec 30, 2016 golang 大法好,无需 bb ,,,哈哈哈 |
64 boneyao Dec 30, 2016 定义一个结构体很麻烦吗? 定义一个不麻烦,但是定义 100 个的时候感觉快崩溃了。 |
65 lijiac Dec 30, 2016 乍看标题以为楼主要黑我 python ,正准备撸起袖子大干一场,结果... |
66 zhiyong Dec 30, 2016 看看 github.com/tidwall/gjson 这个库,或许能帮到你! |
67 shyling Dec 30, 2016 我知道楼主喜欢那种 JsonObject.getXX("name").getYY("name")那种 0v0 |
68 rrfeng Dec 30, 2016 有这样的 json 库。 但是怎么说呢…… |
69 coldwinds Dec 30, 2016 via Android 入乡随俗 |
70 levn Dec 30, 2016 先在静态语言里实现一个动态语言……然后…… |
71 fcfangcc Dec 30, 2016 json.loads(requests.get(url).text) 可以 requests.get(url).json() |
72 woniuge Dec 30, 2016 |
73 Immortal Dec 30, 2016 再说一句 不需要定义结构体的用法 map[string]interface{} 还有 golang 的常用 json 库 上面说的 gjosn 还有一个 simplejson 前者性能更高一些 能直接 get json 里的字段 |
74 fuyufjh Dec 30, 2016 如果结构已知, dict 毕竟要查找,效率和 struct 不能比的。作为一门可以编译到二进制的强类型语言,当然是 struct 如果结构不定,就要传 map[string]interface{}进去 不带你这样不会用就黑的。。 |
76 taowen Dec 30, 2016 可以看一下我写的 jsoniter http://jsoniter.com/java-features.html 解析各种 json 应该要方便很多了 这个是 java 版本的文档, golang 版本的稍后更新 |
77 gouchaoer 易语言可以生成二进制呢 |
78 qwer1234asdf Dec 30, 2016 最蛋疼的是改数据结构, struct 越改越乱。。。 |
79 only0jac OP |
80 a7a2 Dec 30, 2016 写吧 多写点 以后就可以复制粘贴了 那些什么编程语言都用过的人 都是复制粘贴的 程序员不可能同时专注几种语言的 写 java 三年 然后 python 三年 然后 go 三年 这个时候忘掉了 Java 的了。。。 |
81 incompatible Dec 30, 2016 via iPhone @est 搞出「 [1, "1", None, {1: 2, None: 0, 2: 3}] 」这种非标 json 的必要性是? |
82 billlee Dec 30, 2016 只是不同的设计模式而已,就像 Java 的 org.json 与 Jackson 的区别。 |
83 est Dec 30, 2016 |
84 pathbox Dec 31, 2016 静态语言和动态语言的区别。你静态语言不过关啊 lz |
85 mengskysama Jan 1, 2017 用 go 写 api 真心累,特别是操作大量 json 的时候不如 node 和 py 灵活。用了十来个框架下来最喜欢的是 koa ,性能开发效率兼备,至于部署的话...都不是个问题。 |
86 only0jac OP @mengskysama go 部署简单啊,最后只有一个二进制文件, py 部署还得装环境,装虚拟空间, node 没用过,不知道怎么部署 |
87 reyoung1110 Jan 1, 2017 |
88 freestyle Feb 12, 2017 确实,Python 解析 json 比 GO 方便多了 golang 得定义好结构体, 否则用 map[string]interface{} 的话要用的时候每一层都得类型转换.不过 JSON 格式本来就比较灵活,嵌套的话要写一大把结构体-_- response.Result.(map[string]interface{})["files"].([]interface{})[0].(map[string]interface{})["path"].(string) 另外大写是 go 的机制,大写的才能访问到, 可以用结构体注解表示序列化后的小写 key type Aria2JsonRPCReq struct { Method string `json:"method"` Jsonrpc string `json:"jsonrpc"` Id string `json:"id"` Params []interface{} `json:"params"` } |