Exported Vs Unexported
Fast recall
Quick revision
Core answer
Whether you understand Exported Vs Unexported beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The rule, verified:
package math
func Add(a, b int) int { return a + b } // exported
func internalHelper() int { ... } // unexported — importing packages can't see it
var Count int // exported variable
const maxRetries = 3 // unexported constant
type Config struct { ... } // exported typeAn importing package: math.Add works; math.internalHelper is a compile error — undefined.
The rule's scope: it applies uniformly — functions, types, methods, fields, constants, variables, packages' interfaces. The identifier's first character IS the visibility. No public/private/protected keywords; no package hierarchy (Go's packages are flat — no subpackage inheritance).
The design consequence: package APIs are DESIGNED by what you capitalize. The exported surface is the contract; everything else is implementation. Reviewers read a Go package's API by listing its exported identifiers — no separate interface file to maintain.
The conventional pair: an exported function with an unexported helper (the exported one is the stable API; the helper can change freely). Testing still reaches unexported names via the _test.go same-package access — the topic covered earlier.
Exported Vs Unexported
Direct Answer
Capitalized names are exported (public — visible to importing packages). Lowercase are unexported (package-private). One rule, no keywords — the ONLY visibility boundary in Go.
Deep Dive & Architecture
The selector mechanics: the compiler resolves x.Name where the name starts uppercase → find it in the package's export data (the compiled .a file includes only exported identifiers). Unexported names are absent from the export data — the import literally can't reference them, not just 'isn't allowed.' That's why the error is undefined rather than access-denied.
The JSON interplay — the common surprise: encoding/json uses ONLY exported fields. A struct with all unexported fields marshals to {}. The tags can't rescue an unexported field. The DTO pattern (exported wire-type vs unexported domain-type) exists because of this intersection.
The interface satisfaction interaction: a method with an exported name satisfies interfaces across packages; unexported methods only satisfy same-package interfaces. This enables the sealed-interface pattern (an interface with an unexported method can only be satisfied within the package — the marker method technique for closed type hierarchies).
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Exported Vs Unexported in a real project?
- What is a common mistake when using Exported Vs Unexported?
- How would you compare Exported Vs Unexported with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.