Skip to Content
Course content

17: Functions and Multiple Return Values

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

I was thinking about how we usually handle errors in other languages—throwing exceptions, try-catch blocks, the whole nine yards. In Go, the approach is much more grounded. It doesn't throw exceptions for standard errors; it just gives you the error back as a value. But for that to work, a function needs to be able to hand back more than one thing at a time.

The crash we didn't want

Let's start with a simple division function. I'll write it the way you'd write it in almost any other language: one input, one output.

func divide(a, b float64) float64 {
    return a / b
}

At first glance, this looks fine. But what happens if I try to divide by zero? I'll run a quick test in main:

func main() {
    result := divide(10, 0)
    fmt.Println("Result:", result)
}

Running this doesn't actually crash the program (since these are floats, Go gives me +Inf), but in a real application, +Inf is usually a bug waiting to happen. I can't tell if the operation succeeded or if it failed because of bad input. I need the function to tell me, "Hey, I couldn't do this," and then give me a reason why.

Expanding the return signature

Since I can't "throw" an error, I'll try to return it. But wait—if I change the return type to error, I lose the actual result of the division. I can't return just the result OR the error; I need both. This is where Go's multiple return values come in.

I'm going to change the function signature. Instead of a single type, I'll use parentheses to list multiple types:

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

Notice what I did there. The signature (float64, error) tells Go that this function will always hand back two things. When the division fails, I return 0 as a placeholder for the result and the actual error. When it works, I return the result and nil, which is Go's way of saying "no error here."

Unpacking the results

Now, the way I call this function has to change. I can't just assign it to one variable anymore, or the compiler will complain that I'm trying to put two values into one box.

I'll try to capture both:

func main() {
    val, err := divide(10, 0)
    if err != nil {
        fmt.Println("Error happened:", err)
        return
    }
    fmt.Println("Success! Result is:", val)
}

This is the "Go pattern" you'll see everywhere. You get the result and the error, and you immediately check if the error is nil. It feels a bit repetitive at first, but it makes the failure points of your code incredibly explicit. There are no hidden exceptions jumping out from three levels deep in your call stack.

One last thing: what if I only care about the error and not the value? Or vice versa? Go doesn't let you ignore return values entirely. If you don't use a returned value, the code won't compile. To get around this, we use the blank identifier—the underscore _.

// I only care if it failed, not what the result was
_, err := divide(10, 0)
if err != nil {
    fmt.Println("It failed, and that's all I needed to know.")
}

It's a simple mechanism, but it's the bedrock of how Go handles everything from file I/O to database queries.




📋 Practical Task

Build a Temperature Converter with Validation

Create a program that converts Fahrenheit to Celsius. However, you must ensure the input temperature is not below absolute zero (-459.67°F). If the temperature is below absolute zero, the function should return an error.

  • Write a function convertFtoC(f float64) (float64, error).
  • If f is less than -459.67, return 0 and an error using errors.New().
  • Otherwise, return the converted temperature using the formula (f - 32) * 5/9 and nil for the error.
  • In your main function, test the converter with two different values: one valid temperature (e.g., 98.6) and one invalid temperature (e.g., -500).
  • Properly handle the error return in main by printing a custom message if the conversion fails.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.