Go
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions and Methods
-
Section 4: Concurrency
-
Section 5: Packages and Tooling
-
Section 6: More Standard Library
-
Section 7: Building Services
-
Section 8: Advanced Go
-
Section 9: Go in the Cloud-Native Ecosystem
-
Section 10: Data Structures and Algorithms in Go
-
Section 11: Testing and Deployment
-
Section 12: Practical Projects
-
Section 13: More Standard Library Practice
-
Section 14: More Practice Projects
-
Section 15: Design Patterns in Go
-
Section 16: Interview Practice
-
Section 17: Package fmt In Depth
-
Section 18: Package strings and strconv
-
Section 19: Package os and io
-
Section 20: Package time
-
Section 21: Package sort and container
-
Section 22: Package encoding
-
Section 23: Package net/http In Depth
-
Section 24: Package context
-
Section 25: Package regexp and bytes
-
Section 26: Package errors In Depth
-
Section 27: Package crypto and hash
-
Section 28: Package flag and log
-
Section 29: Package sync In Depth
-
Section 30: More Practice Exercises
-
Section 31: Go Modules and Workspaces In Depth
-
Section 32: Generics Deep Dive (Go 1.18+)
-
Section 33: Testing Package In Depth
-
Section 34: More Interview and Whiteboard Practice
-
Section 35: Package math and unicode
-
Section 36: Package path and filepath
-
Section 37: Package database/sql
-
Section 38: Package text/template and html/template
-
Section 39: Package archive and compress
-
Section 40: Lower-Level net Package
-
Section 41: Package runtime and reflect
-
Section 42: Package embed and io/fs
-
Section 43: Go Assembly and CGO Basics
-
Section 44: Building CLIs and TUIs
-
Section 45: Go Performance Tuning
-
Section 46: More Real-World Projects
-
Section 47: Go in Production
-
Section 48: Go Design Patterns
-
Section 49: Go Interfaces Deep Dive
-
Section 50: Final Practice and Review
113: strings.Split, Join, Fields
I was working on a small internal tool yesterday that imports tags from a legacy CSV file. The data is... well, it's a mess. Some rows have tags separated by commas, some have trailing spaces, and some have multiple spaces between words. It reminded me exactly why the strings package has three different ways to handle "breaking apart" a string.
The obvious first choice
My first instinct was to just use strings.Split. It's the most direct approach: you tell Go exactly which character to look for, and it chops the string up into a slice.
package main
import (
"fmt"
"strings"
)
func main() {
input := "golang, concurrency, distributed systems, k8s"
tags := strings.Split(input, ",")
fmt.Printf("%#v\n", tags)
}
Running this gives me: []string{"golang", " concurrency", " distributed systems", " k8s"}. Notice those leading spaces in the second, third, and fourth elements? That's the problem with Split—it is literal. It doesn't care about the context; it just sees a comma and cuts. If I try to look up " concurrency" in a database, it's going to fail because of that one invisible space.
Where Split falls short
I could try to split by ", " (comma plus space) to fix this, but that's a gamble. What if the user forgot the space? Or what if they put two spaces? If the input is "go,backend", splitting by ", " would result in a slice with just one element: the original string. It's too rigid.
This is where I usually pivot to strings.Fields. I remember Fields being a bit "smarter" because it doesn't take a separator argument—it just looks for whitespace.
input := " go concurrency distributed systems "
words := strings.Fields(input)
fmt.Printf("%#v\n", words)
// Output: []string{"go", "concurrency", "distributed", "systems"}
Look at that. It ignored the leading spaces, the trailing spaces, and collapsed those multiple internal spaces into single breaks. It's incredibly clean. The catch? It only works for whitespace. It can't help me with my commas.
Combining the two
So, how do I handle "golang, concurrency, distributed systems"? I can't use Fields because of the commas, and I can't use Split because of the spaces. The solution is to split first, then clean up each piece.
input := "golang, concurrency, distributed systems"
rawTags := strings.Split(input, ",")
var cleanTags []string
for _, tag := range rawTags {
// strings.TrimSpace removes leading/trailing whitespace
trimmed := strings.TrimSpace(tag)
if trimmed != "" {
cleanTags = append(cleanTags, trimmed)
}
}
Now I have a perfect slice: []string{"golang", "concurrency", "distributed systems"}. I've handled the delimiters and the messy spacing.
Stitching it back together
Finally, let's say I need to save these tags back into the database, but the database requires them to be separated by a pipe | instead of a comma. I could write a loop and manually append strings, but that's inefficient because strings in Go are immutable—every concatenation creates a new string in memory.
Instead, I'll use strings.Join. It takes the slice and the separator I want, and handles the memory allocation efficiently in one go.
finalString := strings.Join(cleanTags, "|")
fmt.Println(finalString)
// Output: golang|concurrency|distributed systems
It's a simple pattern: Split to break it, TrimSpace or Fields to clean it, and Join to rebuild it. Once you get that flow down, you can handle almost any messy string input you'll encounter in the wild.
📋 Practical Task
Exercise: User Profile Tag Sanitizer
You are building a user profile system. Users enter their interests as a single string, but they often enter them inconsistently (e.g., " Coding, Go, Cloud Computing , Docker ").
Write a function SanitizeInterests(input string) string that does the following:
- Splits the input string by commas.
- Removes all leading and trailing whitespace from each individual interest.
- Removes any empty strings (in case the user typed
"Go,,Docker"). - Joins the cleaned interests back together using a semicolon
"; "as the separator.
Test Case:
Input: " Golang, , Kubernetes, Microservices , Distributed Systems "
Expected Output: "Golang; Kubernetes; Microservices; Distributed Systems"
There are no comments for now.