Go Language Fundamentals (Caddy Contextualized)¶
This guide highlights key Go concepts compared to Python, pointing directly to how they are implemented in Caddy's codebase.
1. Pointers vs. Value Semantics¶
Go passes variables by value (copies them) unless you use pointers (*).
Code Examples in Caddy:¶
- Pointer Receiver: Look at caddy.go:L524-530:
The receiver
(m *Logging)uses an asterisk*because it needs to modify the fields on the activeLoggingstruct itself without making a copy. - Passing by Pointer: Look at caddy.go:L104:
cfg *Configindicates that the function takes a pointer to the config object so it can read and update the original memory representation rather than copying the entireConfigstruct.
2. Error Handling (The Early Return Pattern)¶
Go functions return errors alongside results, checked with if err != nil.
Code Examples in Caddy:¶
- Checking and Returning Early: Look at caddy.go:L104-110:
If
json.Marshal(cfg)fails, the function exits immediately returning theerr. If it succeeds, the code flows down without being nested inside anelseblock.
3. Arrays, Slices, and Maps¶
- Slice (Dynamic List): Look at caddy.go:L445:
[]stringcreates a dynamically-sized list of strings to keep track of which apps started successfully. - Map (Hash Table/Dictionary): Look at caddy.go:L84:
Maps keys (strings) to values (
Appinterface instances).
4. Visibility (Capitalization)¶
Go uses casing to define access scope instead of keywords like public or private.
Code Examples in Caddy:¶
Look at caddy.go:L68-84:
* Exported (Public): Config and fields like Admin, Logging, StorageRaw are uppercase so that external packages can use them.
* Unexported (Private): apps and failedApps are lowercase so they can only be read/written inside the caddy package.