Skip to content
tezvyn:

Serialize a Go struct to JSON and contrast with Rust

Source: go.devEasyHow cards are made

This tests fluency in Go's encoding/json versus Rust's derive macro ecosystem. Go: call json.Marshal on exported fields; Rust: derive Serialize, then serde_json::to_string. Red flag: claiming Rust uses std-only serialization or that Go needs external crates.

What's really being asked

This question checks whether you understand the design philosophy behind each language's serialization stack. Go ships a complete reflection-based JSON encoder in its standard library because Google internal style favored batteries-included tooling with zero dependency management. Rust deliberately keeps serialization out of the standard library and delegates to serde because Rust's trait system and proc macros let third-party crates achieve zero-cost abstraction and type safety that would be hard to evolve inside std.

The full answer

First, explain that Go uses encoding/json and the json.Marshal function, which relies on reflection to inspect struct fields at runtime. Mention that only exported fields, those starting with an uppercase letter, are serialized, and that struct tags like json name or json name omitempty control the output keys and omission behavior. Second, explain that Rust's idiomatic path is adding serde and serde_json as dependencies, deriving the Serialize trait on a struct, and calling serde_json to_string. Third, contrast the two: Go's approach works immediately with no module system friction but pays a runtime reflection cost and offers less compile-time verification, while Rust's approach requires explicit dependencies and a derive macro but produces strongly typed, often faster code with compile-time guarantees. Fourth, note that Rust's standard library is minimal by design to avoid locking in a single serialization format and to let the ecosystem iterate.

The mistakes people make

A major red flag is insisting that Rust has a standard-library JSON serializer comparable to Go's encoding/json. Another is claiming that Go requires external packages for basic JSON work. Some candidates also confuse Rust's derive macro with runtime reflection or suggest that Go's struct tags are required for all serialization, missing that field names are used by default. Finally, saying that serde is part of the Rust standard library shows a lack of familiarity with the crate ecosystem.

What usually comes next

An interviewer might ask how you handle unknown or dynamic JSON shapes in each language, which leads to discussing Go's empty interface and type assertions versus Rust's Value type from serde_json. They might probe performance by asking about json.Encoder in Go versus streaming serialization in serde_json, or ask how you skip fields, use custom marshalers in Go, or implement Serialize manually in Rust for legacy formats. A security angle could involve asking how each language handles untrusted input size or recursion limits.

A concrete example

In Go, defining a Person struct with Name as a string using the json name tag and Age as an int using the json age tag and then calling json.Marshal on an instance yields a byte slice and an error. The tag renames the field, and omitempty could drop zero values. In Rust, the equivalent is placing derive Serialize above a struct Person with name as String and age as u32 and then calling serde_json to_string with a reference to the instance. The derive generates the trait implementation at compile time, and serde_json handles the actual encoding without runtime reflection on the struct metadata.

Interview question

Which statement accurately contrasts JSON serialization approaches in Go and Rust?

  • a.Rust's standard library provides a built-in JSON serializer comparable to Go's encoding/json, avoiding the need for external crates.
  • b.Both languages use runtime reflection to inspect struct fields during JSON serialization, with Go using struct tags and Rust using derive macros.
  • c.Go's standard library includes a reflection-based JSON encoder, while Rust relies on external crates like serde to derive serialization traits at compile time.Correct
  • d.Go requires external packages for basic JSON serialization, unlike Rust which includes serde in its standard library.
Why?

Go ships encoding/json in its standard library and uses runtime reflection, whereas Rust intentionally omits serialization from std and delegates to external crates like serde for compile-time derived traits. Distractor B is tempting because derive macros can look like reflection, but they generate code at compile time rather than inspecting types at runtime.

Just read this? Test yourself on what you have been reading.

Read the original → go.dev

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on go — each one lists the topics its interview covers.

See open roles