22.7 unicode and unicode/utf8: Working with Runes

Right, let’s talk about text. You’ve probably been happily using string for everything, thinking “it’s just text.” Go’s string is a fantastic abstraction, but it’s built on a lie of omission. Under the hood, a string is a read-only slice of bytes ([]byte). Not characters. Bytes. And this is where the entire world of unicode and unicode/utf8 comes crashing into our pleasant little program. The problem is simple: the world uses more than 128 characters (the limit of ASCII). My last name has an “é”; that’s one character, but it’s represented by two bytes in UTF-8. If you try to process it by just indexing the string (s[0], s[1]…), you’re slicing through those bytes and getting utter garbage. The crucial concept here is the rune.

22.6 bytes.Buffer, bytes.Reader, and Byte Manipulation Functions

Right, let’s talk about bytes. You’ve been playing with strings, and they’re lovely, but sometimes you need to get your hands dirty. Strings are immutable, which is a fancy way of saying they’re read-only. You can’t change a string; you can only create new ones. This is great for safety, but terrible for performance when you’re building something up piece by piece. That’s where bytes.Buffer comes in—it’s your mutable, in-memory scratchpad for assembling byte slices (which are often strings in disguise).

22.5 strconv: Atoi, Itoa, ParseFloat, FormatFloat, ParseBool

Right, so you’ve printed some stuff with fmt, you’ve sliced and diced with strings, and now you need to make sense of the messy, chaotic real world where data doesn’t come neatly wrapped as a string or an int. It comes as text files, HTTP headers, user input—a veritable soup of digits and letters. This is where strconv (short for “string conversion”) becomes your best friend. It’s the unsung hero that does the gritty, unglamorous work of turning strings into numbers and booleans and back again. It’s not pretty, but it’s absolutely essential.

22.4 strings.Reader and strings.NewReader

Right, let’s talk about strings.Reader. You’ve got a string. It’s sitting there in memory, looking perfectly innocent. You need to read from it, maybe seek around in it, treat it like a stream of data. You could keep track of an index variable yourself, slicing and dicing until your code looks like a deli counter on a Saturday morning. Or, you could be civilized and use strings.Reader. Think of a strings.Reader as giving your string an identity crisis: it desperately wants to be an io.Reader, an io.ReaderAt, an io.Seeker, and an io.ByteScanner. And the wonderful part is, it succeeds brilliantly. It wraps a string and provides a read pointer, letting you treat that immutable string as a consumable, seekable stream. It’s one of those beautifully simple pieces of the standard library that just works exactly how you’d hope.

22.3 strings: Contains, HasPrefix, Split, Join, Replace, Builder

Right, let’s talk about strings. This package is the duct tape and WD-40 of your Go career. You’ll use it constantly, and if you think it’s just a bunch of simple helpers, you’re missing half its power and all its gotchas. It’s designed to work with immutable, UTF-8 encoded strings, and once you internalize that, its functions stop being magic and start being obvious tools. Contains, HasPrefix, HasSuffix: The Quick Checks These are your first line of defense. Need to know if a string has a thing, starts with a thing, or ends with a thing? Here you go. They do exactly what they say on the tin.

22.2 fmt.Errorf, fmt.Sprintf, and fmt.Fprintf

Right, let’s talk about fmt’s workhorses for creating strings and errors. You’ve seen fmt.Println for basic output, but Sprintf, Fprintf, and Errorf are where you go when you need to build things, not just shout them into the terminal. They all use the same familiar verb system (%s, %v, %d, etc.), but their destination is what sets them apart. The Builder: fmt.Sprintf Think of fmt.Sprintf (the ‘S’ stands for string) as your string constructor. It doesn’t print anything. Instead, it takes your format string and arguments, performs the formatting magic, and returns the finished string product for you to use wherever you need it. This is your go-to for dynamic strings.

22.1 fmt: Printing, Scanning, and Format Verbs

Right, let’s talk about fmt. This is probably the first package you ever used in Go, printing a timid “Hello, World” to the console. But don’t let its simplicity fool you; fmt is a workhorse. It’s how you talk to your program, how you debug in a panic, and how you present data to a user. It’s also where a lot of new Gophers get their first papercut. I’m here to make sure you get the good stuff without the bloodshed.

— joke —

...