感觉 golang 比 Java 还难读, 难学

2023-02-23 13:20:57 +08:00
 echoless

要解析的 json, 格式不完美. 比如

[{
"name": "Abyssin",
"price": 500,
"location": "Lviv",
"image": "https://olxua-ring02.akamaized.net/images_slandocomua/476948786_2_1000x700_abissenysh-chempion-fotografii.jpg"
},
{
"name": "Abyssin",
"price": "550",
"location": "Lviv",
"image": "https://olxua-ring10.akamaized.net/images_slandocomua/342850976_3_1000x700_abidetki-koti_rev006.jpg"
}]

price 实际上是个 int 但是有些值是 string. 加 tag 就没啥用了, 只能自己写 UnmarshalJSON

好奇看了一下

json/decode

// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
// If it encounters an Unmarshaler, indirect stops and returns that.
// If decodingNull is true, indirect stops at the first settable pointer so it
// can be set to nil.
func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
	// Issue #24153 indicates that it is generally not a guaranteed property
	// that you may round-trip a reflect.Value by calling Value.Addr().Elem()
	// and expect the value to still be settable for values derived from
	// unexported embedded struct fields.
	//
	// The logic below effectively does this when it first addresses the value
	// (to satisfy possible pointer methods) and continues to dereference
	// subsequent pointers as necessary.
	//
	// After the first round-trip, we set v back to the original value to
	// preserve the original RW flags contained in reflect.Value.
	v0 := v
	haveAddr := false

	// If v is a named type and is addressable,
	// start with its address, so that if the type has pointer methods,
	// we find them.
	if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
		haveAddr = true
		v = v.Addr()
	}
	for {
		// Load value from interface, but only if the result will be
		// usefully addressable.
		if v.Kind() == reflect.Interface && !v.IsNil() {
			e := v.Elem()
			if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) {
				haveAddr = false
				v = e
				continue
			}
		}

		if v.Kind() != reflect.Pointer {
			break
		}

		if decodingNull && v.CanSet() {
			break
		}

		// Prevent infinite loop if v is an interface pointing to its own address:
		//     var v interface{}
		//     v = &v
		if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
			v = v.Elem()
			break
		}
		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		if v.Type().NumMethod() > 0 && v.CanInterface() {
			if u, ok := v.Interface().(Unmarshaler); ok {
				return u, nil, reflect.Value{}
			}
			if !decodingNull {
				if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
					return nil, u, reflect.Value{}
				}
			}
		}

		if haveAddr {
			v = v0 // restore original value after round-trip Value.Addr().Elem()
			haveAddr = false
		} else {
			v = v.Elem()
		}
	}
	return nil, nil, v
}

感觉 java 感觉清爽很多. java 感觉不需要学, 看看 ArrayList HashMap 这些接口就可以写了,语法也比较简单. golang 真是各种奇技淫巧满天飞.

7431 次点击
所在节点    程序员
65 条回复
echoless
2023-02-23 16:42:30 +08:00
我把完整的代码列出来

https://go.dev/play/p/8sFRipQ1hAn

就处理一个 json

要用到懂

1. interface (golang 默认的, 否则不了解 UnmarshalJSON 咋回事, 这个看文档是最简单的途径, 目前我还没有入门怎么看 golang 文档最快, 容易晕)
2. pointer 这玩意有时候容易晕, 比 c 容易, 但是跟 java, python 比是复杂了.
3. type 声明 或者 struct

```
type StrInt int


type IntStr struct {
value int
}
```
总体看上来, 没觉得哪里比其他语言简单. 上面有人讲, 你用别的语言(强类型)也一样的复杂度. 但是别的语言不像 golang 这种, 宣扬 less is more.
echoless
2023-02-23 16:43:45 +08:00
@vcbal 我就是个初学着, 一个整天宣扬自己简单的语言, 学习有疑问, 就说是人的原因. 那也对.
guyanyouyou
2023-02-23 16:44:09 +08:00
@wuhaoecho 学好以后发现,在 golang 的擂台上,不仅看到了原来在 python 擂台一起卷的朋友,还有前端、PHP 和 Java 的小伙伴
dongtingyue
2023-02-23 17:22:03 +08:00
json 这方面确实不如 js 方便
fregie
2023-02-23 17:50:54 +08:00
没有语言是万能的,如果你觉得在某个方面 go 不好用,那么你就不该用 go 来做.
明明 go 都不是一个面向对象的语言,非要和面向对象的语言比写业务,这才是出问题的地方
zong400
2023-02-23 18:05:08 +08:00
只有 #39 是老实人
bxb100
2023-02-23 18:21:35 +08:00
rust 杀手锏 json -> struct
gogorush
2023-02-23 18:59:28 +08:00
golang 说 别跟我谈 JSON 和 MySQL 的 ORM 不然我发火了
echoless
2023-02-23 19:23:40 +08:00
@gogorush 不要吓我 orm 还没用过
sealinfree
2023-02-23 21:08:15 +08:00
@a132811 赞,学习了
lixintcwdsg
2023-02-23 21:20:19 +08:00
写代码 10 多年了哈
js as ts java php python bash 都写过一些,java 写的尤其多
架构什么的也都搞
go 的问题很早就和人讲过了,和过去 node.js 其实类似,因为标准轮子还是太少,各种私人写的又很重要的框架、工具很多,这个实际上会有大问题。维护起来更麻烦。
java 最大的好处就是 web 开发东西都很明确 spring 解决大部分问题,其余一些通用的解决其他问题,所以写出来东西都类似,谁接手都没啥问题。
panlatent
2023-02-23 22:46:56 +08:00
毕业后经过 PHP -> Go -> (C# ...) -> C++(重学) 这么学一圈。对 Go 的理解就是 Better C ,至于语法,各有权衡,各有取舍,但不一定都是精心设计出来的(专指) :D
jeesk
2023-02-23 23:46:00 +08:00
觉得 java 好阅读的可以看看 google juice 的代码。觉得 golang 好读的可以看看 docker 的代码。
echoless
2023-02-23 23:47:12 +08:00
@jeesk 诛心了这是
hzxxx
2023-02-24 01:07:48 +08:00
估计还没到呢,Java boy ,等你再学 protoc 、orm 、wire 、还有微服务,你就会怀念以前 spring 全家桶梭哈的日子了
WilliamYang
2023-02-24 01:53:17 +08:00
你不够了解 Golang 而已,json.Number ,json.RawMessage 了解一下
Nazz
2023-02-24 07:51:07 +08:00
刚学 go 的时候我也很疑惑,json_encode, json_decode 和万能的 array 用习惯了而已
jorneyr
2023-02-24 09:37:33 +08:00
写了一年 Go ,终于习惯了 Go 的写法,Java 和 Go 已经可以平滑切换。
naturekingfree
2023-02-24 09:39:16 +08:00
@NeoZephyr 我也是
macscsbf
2023-02-24 09:51:50 +08:00
你说说看哪里难阅读了,不然我也不知道怎么去解答你的疑问

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

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

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

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

© 2021 V2EX