Skip to content

Reflection and unsafe: resources

Level: 301 · where the claims on this chapter's pages come from, and what to read next

One line: The package docs and The Laws of Reflection settle almost every question; the release notes for 1.14, 1.17, 1.20, 1.21 and 1.25 are where the answers changed; and the books are best read for their examples, with the caution sections taken seriously.

Primary sources

Books

  • Alan A. A. Donovan and Brian W. Kernighan, The Go Programming Language (Addison-Wesley, 2015) — chapter 12, "Reflection": "Why Reflection?", "reflect.Type and reflect.Value", "Display, a Recursive Value Printer", "Setting Variables with reflect.Value", "Accessing Struct Field Tags", "Displaying the Methods of a Type" and "A Word of Caution"; chapter 13, "Low-Level Programming": "unsafe.Sizeof, Alignof, and Offsetof", "unsafe.Pointer", "Example: Deep Equivalence" and "Another Word of Caution". The Display and S-expression examples are still the best worked reflection code in print.
  • Jon Bodner, Learning Go, 2nd ed. (O'Reilly, 2024) — chapter 16, "Here Be Dragons: Reflect, Unsafe, and Cgo": "Reflection Lets You Work with Types at Runtime", "Types, Kinds, and Values", "Make New Values", "Use Reflection to Check If an Interface's Value Is nil", "Use Reflection to Write a Data Marshaler", "You Can Build Structs with Reflection, but Don't", "Reflection Can't Make Methods", "Use Reflection Only if It's Worthwhile", "unsafe Is Unsafe", "Using Sizeof and Offsetof", "Using unsafe to Convert External Binary Data", "Accessing Unexported Fields", "Using unsafe Tools"; and chapter 13, "The Standard Library": "Using Struct Tags to Add Metadata".
  • Go in Practice, 2nd ed. (Manning, 2025) — chapter 13, "Reflection, code generation, and advanced Go": "Three features of reflection", "Structs, tags, and annotations" and "Generating Go code with Go code".
  • Adam Freeman, Pro Go (Apress, 2022) — chapter 27, "Using Reflection"; chapter 28, "Using Reflection, Part 2" ("Inspecting Struct Tags", "Setting Struct Field Values", "Creating, Copying, and Appending Elements to Slices"); chapter 29, "Using Reflection, Part 3" ("Working with Channel Values", "Selecting from Multiple Channels"). Exhaustive on the API, method by method.
  • Miki Tebeka, Effective Go Recipes (Pragmatic, 2024) — chapter 2, "Serializing Data", Recipe 14, "Parsing Struct Tags".
  • Burak Serdar, Effective Concurrency in Go (Packt, 2023) — chapter 5, "Worker Pools and Pipelines": the side note that reflect.Select is the fan-in for a dynamic number of channels.

Not on the shelf

Talks and videos

Read with care

  • Any source that reads a []byte as a string through reflect.SliceHeader / StringHeader — deprecated since Go 1.20; unsafe.String and unsafe.Slice replace them, and staticcheck flags the old form.
  • Benchmarks of reflect.ValueOf published before Go 1.21 — they include a heap allocation that no longer happens.
  • Advice that Interface() followed by a type assertion is the only way to get a typed value out — true until Go 1.25's TypeAssert, which also removes the copy for an addressable value.
  • Tutorials that store an address in a uintptr "to keep it small" — invalid under pattern 2 of the unsafe docs, flagged by vet, fatal under -race.
  • The Go Programming Language's Sizeof table was written for Go 1.5: the numbers are the same on today's 64-bit platforms, but check them with a program, as chapter 14 does.

Checked 2026-09-23.