Skip to Content
Course content

107: Println, Printf, and Sprintf Family

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When you're first starting out with Go, your instinct is probably to treat strings the way you do in JavaScript or Python—just smashing things together with the + operator. It feels natural. You have a variable, you have a label, and you want them to appear on the same line. But once you start dealing with mixed types, like integers or floats, that approach falls apart fast.

The Concatenation Headache

Imagine you're building a small CLI tool to report the status of a server. You've got a server name, an uptime count in seconds, and a CPU load percentage. If you do this the naive way, your code ends up looking like a cluttered mess of type conversions:

name := "production-web-01"
uptime := 86400
cpuLoad := 12.5

fmt.Println("Server: " + name + " | Uptime: " + strconv.Itoa(uptime) + "s | Load: " + fmt.Sprintf("%.2f", cpuLoad) + "%")

I've seen this in plenty of junior PRs. It's tedious to write and even harder to read. You're constantly jumping between strconv.Itoa for integers and fighting with fmt.Sprintf just to get a decimal point right, all while managing a dozen quotation marks and plus signs. It's brittle; if you want to change the order of the fields, you have to surgically rearrange the entire string concatenation chain.

Letting Printf Do the Heavy Lifting

This is where fmt.Printf becomes your best friend. Instead of building a string piece by piece, you define a template and then plug your variables into it. It separates the "what the output looks like" from "what the data is."

fmt.Printf("Server: %s | Uptime: %ds | Load: %.2f%%\n", name, uptime, cpuLoad)

Notice how much cleaner that is. We use "verbs" like %s for strings, %d for integers, and %.2f to tell Go we want a float with exactly two decimal places. I personally find this much more maintainable because if my boss tells me the uptime needs to be in hours instead of seconds, I just change the variable and the template without worrying about breaking the surrounding string glue. Just remember that Printf doesn't add a newline automatically—you have to add that \n at the end yourself, or your next print statement will be glued to the end of this one.

Choosing Between Println and Sprintf

Now, you might be wondering why we even have Println or Sprintf if Printf is so powerful. It comes down to intent and destination.

Use fmt.Println when you're just debugging or dumping data. It's the "quick and dirty" option. It automatically adds spaces between arguments and puts a newline at the end. I use it mostly for logging something simple to the console where I don't care about the exact formatting.

But here is the crucial part: Printf and Println send their output directly to the standard output (your terminal). What happens if you need that formatted string to actually do something? Maybe you need to send it as an email body, save it to a database, or return it as part of an error message. That's where fmt.Sprintf comes in.

// This doesn't print anything to the screen. 
// It returns a string that we can store in a variable.
statusMessage := fmt.Sprintf("Alert: Server %s is overloading at %.2f%%", name, cpuLoad)

if cpuLoad > 90.0 {
    sendAlertEmail(statusMessage)
}

Think of Sprintf as "String Print Format." It uses the exact same verb system as Printf, but instead of shouting the result into the void of the console, it hands the result back to you as a usable string variable. If you find yourself using + to build a string that you're then passing into another function, you should almost certainly be using Sprintf instead.




📋 Practical Task

Build a Bank Transaction Receipt Formatter

You need to create a program that formats a bank transaction into a clean, human-readable receipt. Instead of just printing the values, you must use a combination of the fmt family to handle different requirements.

Requirements:

  • Create three variables: accountHolder (string), amount (float64), and transactionID (int).
  • Use fmt.Sprintf to create a formatted string called receiptHeader that looks like: "Account: [Name] | ID: [ID]".
  • Use fmt.Printf to print a line showing the amount, ensuring it is formatted to exactly two decimal places with a currency symbol (e.g., "Amount: $125.50").
  • Use fmt.Println to print a final footer message: "Thank you for banking with us!".

Your output should look similar to this:

Account: Jane Doe | ID: 98765
Amount: $1250.75
Thank you for banking with us!
Rating
0 0

There are no comments for now.

to be the first to leave a comment.