Implicit Interface Implementation
In Go, interfaces are implemented implicitly. A type satisfies an interface by simply implementing its methods; there is no 'implements' keyword. This decouples the definition of the interface from…
Open snippet →Read these Intermediate Go snippets line by line — each one comes with a written breakdown of what the code does and why.
In Go, interfaces are implemented implicitly. A type satisfies an interface by simply implementing its methods; there is no 'implements' keyword. This decouples the definition of the interface from…
Open snippet →Functions in Go are first-class citizens. You can define custom function types, which is useful for implementing patterns like Strategy or Middleware, allowing behavior to be passed as arguments.
Open snippet →Go 1.13+ introduced error wrapping using the %w verb in fmt.Errorf. This allows you to add context to an error while still being able to check for the original sentinel error using errors.Is.
Open snippet →The 'select' statement lets a goroutine wait on multiple communication operations. Using a 'default' case allows for non-blocking sends and receives, executing immediately if no channel is ready.
Open snippet →Go uses struct embedding to achieve composition. When a type is embedded without a field name, its methods and fields are 'promoted' to the outer struct, allowing them to be accessed directly.
Open snippet →The recover built-in function allows a program to regain control of a panicking goroutine. It must always be called within a deferred function to effectively catch the panic before the program exits.
Open snippet →When using append, Go may need to reallocate the underlying array if the capacity is exceeded. By providing a capacity hint in make(), you reduce CPU overhead and memory fragmentation.
Open snippet →A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for, each worker calls Done when finished, and Wait blocks until all…
Open snippet →Table-driven testing is a Go idiom where test cases are defined as a slice of anonymous structs. This makes it easy to add new scenarios and ensures consistent testing logic across multiple inputs.
Open snippet →The context package is essential for managing the lifecycle and cancellation of concurrent processes. WithTimeout creates a derived context that automatically cancels itself after a specified durat…
Open snippet →In Go, a slice is a header containing a pointer to a backing array, a length, and a capacity. Slicing an existing slice creates a new slice header pointing to the same backing array. Modifying elem…
Open snippet →For security-sensitive tasks like generating session IDs, password reset tokens, or API keys, Go's standard library provides the crypto/rand package. Unlike math/rand which is pseudo-random and pre…
Open snippet →A timing attack allows an attacker to guess secrets (like API keys or password hashes) by measuring how long a comparison takes. Standard string comparisons (==) exit early on the first mismatched…
Open snippet →In Go, strings are read-only slices of bytes. UTF-8 characters like emojis or accented letters occupy multiple bytes. Slicing or indexing a string directly accesses raw bytes, which can corrupt mul…
Open snippet →In Go, maps are not safe for concurrent use. If two goroutines write to a map at the same time, or one reads while another writes, the program will panic with a fatal concurrent map write error. To…
Open snippet →The sync.Once type guarantees that a function is executed exactly once across all goroutines. This is commonly used for thread-safe lazy initialization, such as setting up global configurations, co…
Open snippet →Custom error types in Go allow carrying structured context alongside the error message. By implementing the Unwrap method, the custom error integrates with Go's standard library wrapping mechanics,…
Open snippet →To prevent concurrent operations from blocking indefinitely, you can implement timeouts using a select statement paired with time.After. The time.After function returns a channel that sends the cur…
Open snippet →Go's context package enables structured cancellation signals and deadlines to propagate across API boundaries and goroutines. Using a context prevents resource leaks by cleanly notifying background…
Open snippet →Table-driven testing is an idiomatic pattern in Go. By defining a list of test cases in a slice of structs, you can easily add new test inputs and expected outputs without duplicating assertion log…
Open snippet →In Go, rate limiting can be implemented using time.Ticker. A ticker sends a signal over its channel C at a regular interval. By reading from ticker.C before handling each request, we block the loop…
Open snippet →A worker pool manages a concurrent set of goroutines executing tasks from a shared queue. This pattern prevents uncontrolled goroutine creation and resource exhaustion. We use a sync.WaitGroup to t…
Open snippet →To filter elements in a slice without allocating a new backing array, you can perform an in-place filter. By maintaining an index n of valid items, you overwrite elements sequentially in the same s…
Open snippet →The sync.WaitGroup is used to coordinate execution flow when starting multiple concurrent tasks in separate goroutines. By calling Add(1) before starting a goroutine and Done() when it exits, we ma…
Open snippet →In Go, errors can wrap other errors to provide contextual information while preserving the original error's type and details. By implementing the Unwrap() error method on a custom error struct, you…
Open snippet →To sort a custom collection in Go using the standard sort package, you implement the sort.Interface interface. This interface requires three methods: Len(), Swap(i, j int), and Less(i, j int) bool.…
Open snippet →Go's standard library relies heavily on interfaces like io.Reader. By wrapping an existing io.Reader inside a custom struct and implementing the Read([]byte) (int, error) method, you can perform st…
Open snippet →By default, Go's json.Marshal formats types using default serialization rules. By implementing the json.Marshaler interface (defining a MarshalJSON() ([]byte, error) method), you can customize exac…
Open snippet →In Go, a slice is a header pointing to an underlying array. When you create a sub-slice from a large slice (e.g., largeSlice[:2]), the garbage collector cannot reclaim the underlying array because…
Open snippet →By implementing the fmt.Formatter interface, a custom Go type can define precisely how it formats across different verbs in the fmt package. This allows you to handle custom custom representation l…
Open snippet →