Hacker News new | ask | show | jobs
by jamieomatthews 4212 days ago
For anyone wondering why this is necessary, as some others in this thread have mentioned, the standard go way to deserialize json is to pass a pointer to a struct, and the system will "fill" it with the json. There is no easy way to sort of "parse" json piece by piece, which is what this library provides
6 comments

> There is no easy way to sort of "parse" json piece by piece

You mean like this? http://play.golang.org/p/mMh7HGuTbe

You're still parsing the entire JSON document at once. I believe what OP meant was getting a nested property without all the overhead of writing structs or parsing the entire JSON object into an interface{}, []string, map or whatever else is appropriate.
The jason package implementation decodes the entire JSON object to an interface{} using the standard encoding/json package.
> There is no easy way to sort of "parse" json piece by piece, which is what this library provides

Well, you can use json.RawMessage to delay decoding until other values are known[0].

However, this still requires that the input set is known at compile-time, which may not always be the case (some APIs sadly use a highly variable JSON schema, which can only be determined at runtime.)

You also don't need to pass a pointer to a struct. For example, you can pass an interface{}, which allows you to decode data into a type that is specified by the calling function, which I made heavy use of in this Twitter client library, for example[1].

(This is more or less how encoding/json itself works under the surface, when you think about it, but oftentimes people forget to take advantage of this idiom in practice.)

[0] http://golang.org/pkg/encoding/json/#RawMessage

[1] https://github.com/ChimeraCoder/anaconda/blob/master/users.g...

>For anyone wondering why this is necessary, as some others in this thread have mentioned, the standard go way to deserialize json is to pass a pointer to a struct

I sometimes have trouble understanding Go. It kind of seems to retain a lot of the bad parts of C in terms of developer-friendliness, while still being relatively slower than C and garbage-collected.

What are you having trouble with in this instance? Pointers and structs? Both are very simple, well understood concepts. Their implementation in Go is also more syntactically clear than in C.
I understand pointers and structs just fine, it's just that you would think a modern language like Go would avoid use of pointers to structs and "bring-your-own-buffer" type calling conventions except wherever possible. It makes for ugly developer APIs, in my opinion.

That is, in a "friendly" language I expect to generate JSON like this (in pseudocode):

    HashMap parsed = JSON::parse("{1: 2}");
not

    JSONObj obj;
    JSON::populate(&obj, "{1: 2}");
The former is how it might work in a dynamically typed language. In a statically typed language, like Go, there are great benefits to decoding into the fields of struct with fields of known types.
IMHO there is something rigid in Go,like C rigid.Sure,there is no manual memory management.But a modern language shouldnt need explicit pointers.
> a modern language shouldnt need explicit pointers

I don't understand this. Can you clarify why you think this is a good idea?

My experience with languages that have implicit "references" (Python, Java, JavaScript) is that it's not clear when you're sharing and when you're copying data, leading to bugs and unnecessary allocations, respectively.

Passing a pointer to a struct is just one way to use the standard Go package. You can also pass a pointer to an interface{}, []interface{} or map[string]interface{} depending on how much of the structure you know. You can also use these types in struct fields.
I've made something very similar for a current project and haven't gotten around to extracting it as a separate pkg yet, but it is much more loose on the coercion, e.g. when calling String() on an int(5) you will get back "5", etc.
Or to do a streaming parse with json.Decoder.