24.9 maps Package (Go 1.21+): Keys, Values, Clone, Equal

Right, let’s talk about the maps package. You’ve been writing Go for a while, and you’ve undoubtedly written the same three map-related functions a dozen times: one to get a slice of the keys, another for the values, and a third to check if two maps are deeply equal. It’s a rite of passage, like building your own IKEA furniture with a butter knife. It works, but you always feel a little silly doing it when a proper toolkit is available.

24.7 sort.Search: Binary Search

Right, so you want to find something in a sorted slice. You could just loop through it, checking each element one by one. That’s a linear search, and it’s fine for your grocery list. But if you’re dealing with a sorted list of 100,000 users by ID, checking every single one is like reading the dictionary cover-to-cover to find the word “zebra.” It works, but it’s an intellectual embarrassment. This is where sort.Search comes in. It’s Go’s built-in implementation of a binary search, and it’s so fast it feels like cheating. The core idea is simple: you start in the middle of your sorted slice. If the element there is less than your target, you know your target must be in the right half; if it’s greater, it’s in the left half. You then repeat the process on that half, and so on, halving the search space each time. You go from 100,000 elements to 50,000 to 25,000 to… you get the idea. You’ll find your target (or confirm its absence) in about 17 steps. Logarithmic time. Chef’s kiss.

24.6 sort.Slice and sort.Stable: Sorting with Less Functions

Right, let’s talk about sorting slices. You’ve probably tried to sort a []int with sort.Ints and it was blissfully simple. But then you tried to sort a slice of your own structs—a []Person by last name, maybe—and you hit a wall. The built-in sort package doesn’t know your Person from a hole in the ground. That’s where sort.Slice and sort.SliceStable come in. They are your gateway to sorting anything, and they do it by making you do the heavy lifting. It’s the “I’ll hold the light, you fix the engine” approach to sorting.

24.5 math/rand/v2 (Go 1.22+): Seeding and Distributions

Alright, let’s talk about the new hotness: math/rand/v2. It landed in Go 1.22, and frankly, it’s about time. The old math/rand was like that reliable but slightly cranky old car that started most days. The new one is that car’s sleeker, more efficient descendant, with a few of the weird quirks finally fixed. We’re going to focus on two of the biggest upgrades: the end of the tedious seeding dance and the fantastic new buffet of distributions.

24.4 math and math/big: Numeric Operations

Let’s be honest: you’re not here because you love math. You’re here because you need to get numbers to behave. Go’s math package is your no-nonsense Swiss Army knife for this. It’s not a symbolic math library; it’s a collection of fast, precise functions for common (and some uncommon) operations. It’s the kind of friend who will tell you that 0.1 + 0.2 doesn’t equal 0.3 in floating-point land and then hand you the right tool to deal with it.

24.3 time.Ticker and time.Timer

Right, let’s talk about two of Go’s most useful and, frankly, most misused constructs: time.Ticker and time.Timer. These are your tools for telling your code to “do this thing later” or “do this thing repeatedly.” They’re deceptively simple, and that’s where everyone gets tripped up. I’ve seen more production bugs related to these than I care to admit, so pay attention. The core thing to understand is that both Ticker and Timer are channels. That’s it. Their entire API is a single channel, C, of type <-chan time.Time. Their job is to send a value on that channel at the appointed time. The difference is in their cadence: a Timer fires once; a Ticker fires repeatedly until you stop it.

24.2 time.Duration: Nanoseconds, Milliseconds, and Readable Literals

Let’s talk about time.Duration. It’s one of those things in Go that seems simple until you realize you’ve been doing it wrong for six months. At its heart, a Duration is just an int64 underneath, representing a span of time in nanoseconds. Yes, you read that right. Not milliseconds, not seconds, but nanoseconds. One billionth of a second. This choice is simultaneously brilliant and, for the uninitiated, a bit absurd. Why? Because it gives you integer precision over a massive range of time—from about 290 years down to a single nanosecond—without touching floating-point math and its attendant rounding errors. It’s the kind of brutally pragmatic design decision Go is famous for.

24.1 time.Time: Parsing, Formatting, and Arithmetic

Right, let’s talk about time.Time. This is the struct you’ll be holding onto for dear life, the one that represents a single, unambiguous moment in time. Think of it not as a clock on the wall, but as a point on a cosmic timeline that everyone, from a server in Tokyo to your laptop, can agree on. It’s the antidote to the madness of time zones and string parsing. We’re going to make it your best friend.

31.7 paste and join: Combining Files Side by Side and by Key

Right, so you’ve sorted your data, you’ve de-duplicated it, you’ve sliced and diced it. Now you’re left with two or more files, each a neat column of information, and you need to put them together. This is where paste and join come in. They are the dynamic duo of horizontal file combination, but they have wildly different personalities and use cases. One is a simple, no-fuss bricklayer; the other is a finicky, key-obsessed database administrator.

31.6 wc: Counting Lines, Words, and Bytes

Right, wc. The name stands for “word count,” which is a bit of a lie because it’s so much more useful than that. It’s the tool you reach for when you need to ask a file the most basic, fundamental questions: “How big are you? How many lines do you have? What’s the deal here?” It’s the digital equivalent of picking up a box and giving it a shake. Let’s start with the simplest, most common invocation. You run wc and give it a file. It gives you back four numbers.

31.5 tr: Translating and Deleting Characters

Right, let’s talk about tr. This is one of those tools that seems almost comically simple until you realize it’s the duct tape of the text manipulation world. It doesn’t read files. It doesn’t do regular expressions. It just does one thing: it translates or deletes characters from its standard input. And it does that one thing blindingly fast and with a ruthless, single-minded efficiency that more powerful tools like sed can sometimes envy for simple tasks.

31.4 cut: Extracting Columns by Delimiter or Byte Position

Right, let’s talk about cut. It’s the command you reach for when you have a nicely structured line of text—a config file, a CSV, the output of another command—and you just want to pull out a specific piece of it. It’s the digital equivalent of taking a scalpel to a log file. Simple concept, right? And it is. Until it isn’t. cut is one of those tools that will work perfectly 99% of the time and then fail in the most spectacularly confusing way the other 1%. I’m here to make sure you’re ready for that 1%.

31.3 uniq: Removing Duplicate Lines (-c, -d, -u)

Right, uniq. The name is a bit of a lie, and that’s the first thing you need to get over your head. It doesn’t magically find all unique lines in a file. No, no. Its job is far more specific, and frankly, a little bit dumb: it only removes adjacent duplicate lines. If you don’t sort your data first, uniq is about as useful as a screen door on a submarine.

31.2 sort -k and -t: Sorting by Column and Field Delimiter

Right, so sort by itself is fine for a quick-and-dirty alphabetical sort of a file. But let’s be honest, your data is rarely that polite. It’s usually in columns, like some kind of data spreadsheet that got lost and ended up in the terminal. This is where sort graduates from a simple tool to a data-wrangling ninja, using the -k (key) and -t (delimiter) options. The basic idea is simple: instead of sorting the entire line, you tell sort to look at a specific part of each line, a specific column or “field.” But as with all things in the shell, the devil is in the details, and those details will bite you if you’re not careful.

31.1 sort: Alphabetical, Numeric, and Reverse Sorting

Right, let’s talk about sort. It’s one of those commands you’ll use so often it becomes a reflex, but it’s also deceptively powerful. Most people get to sort file.txt and call it a day, but that’s like using a sports car to drive to the mailbox and back. We’re going to open the garage door and take this thing for a proper spin. By default, sort does what you’d expect: it reads lines of text and sorts them in ascending order. But here’s the first “gotcha” that trips up everyone, including me on a bad day: it uses the locale’s collating order. This means sort file.txt on your machine and my machine might give slightly different results if we’re in different countries. It’s generally alphabetical, but it knows that in Spanish, for example, “ñ” should sort after “n”. For 99% of what you do, this is fine, but just know the ghost of internationalization is in the machine.

— joke —

...