Naked returns

Now we’re going to look at the third and finaly way to return values from a function in Go. But first a warning. ⚠️ NEVER DO THIS!! ⚠️ What we’re about to look at is commonly referred to as “naked returns” or “bare returns”, and it is widely (though, admittedly, not universally) considered bad practice. It’s honestly a mystery to me why this feature exists in Go, and I wish it didn’t.


Proxying return values

We already saw the “normal” way to return values from functions… But did you know there’s a shortcut if you ever want to directly return the values returned from another function? Return statements … The expression list in the “return” statement may be a single call to a multi-valued function. The effect is as if each value returned from that function were assigned to a temporary variable with the type of the respective value, followed by a “return” statement listing these variables, at which point the rules of the previous case apply.


Three ways to return values

Return statements … There are three ways to return values from a function with a result type: Do you know all three off the top of your head? We’ll be looking at each of them over the coming three days. The return value or values may be explicitly listed in the “return” statement. Each expression must be single-valued and assignable to the corresponding element of the function’s result type. func simpleF() int { return 2 } func complexF1() (re float64, im float64) { return -7.


Returning from a function without a return value

Let’s continue our discussion of return statements by looking at functions that don’t actually return anything… Return statements … In a function without a result type, a “return” statement must not specify any result values. func noResult() { return } Simple enough. Within functions without return values, return must not include any result values. But that doesn’t actually mean the example code you see is good code. In the noResult function, the return statement is actually completely redundant, because the function simply ends on the next line.


Return statements

Return statements A “return” statement in a function F terminates the execution of F, and optionally provides one or more result values. Any functions deferred by F are executed before F returns to its caller. ReturnStmt = "return" [ ExpressionList ] . The good ol’ return statement. We’ve all seen them. There’s a good chance you think you understand them pretty well. And you might. But there are a few subtleties that we’ll be looking at for the next couple of days.


Select statements, conclusion

Select statements … If the selected case is a RecvStmt with a short variable declaration or an assignment, the left-hand side expressions are evaluated and the received value (or values) are assigned. This is to say that, given a select case such as the following, where getAChannel() returns a receiving channel: case value, ok := <- getAChannel() the right-hand side of the assignment operator (<- receiveChannel) is evaluated earlier (back in step 1), and the left-hand side is only evaluated if the case is actually selected.


Execution of a select statement

I’m looking for a new client or two. Could your team use some expert Go help? Reach out, and let’s talk! Select statements … Execution of a “select” statement proceeds in several steps: For all the cases in the statement, the channel operands of receive operations and the channel and right-hand-side expressions of send statements are evaluated exactly once, in source order, upon entering the “select” statement. The result is a set of channels to receive from or send to, and the corresponding values to send.

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.

How-Tos

9 min read


First impressions of Go 1.23's range-over-func feature

If I can knit and crochet, surely I can loop over functions in Go!


Default select case

Select statements … There can be at most one default case and it may appear anywhere in the list of cases. As with a switch statement, a select statement may include either zero or one default case. The behavior of a select statement is changed in important ways when a default case is included. The details are coming soon, but I think this is a good chance to jump ahead a bit and elaborate.


Select statements

Join me again today as I’ll be coding and answering questions on my livestream. Join me Select statements A “select” statement chooses which of a set of possible send or receive operations will proceed. It looks similar to a “switch” statement but with the cases all referring to communication operations. SelectStmt = "select" "{" { CommClause } "}" . CommClause = CommCase ":" StatementList . CommCase = "case" ( SendStmt | RecvStmt ) | "default" .


Go statements, conclusion

Today we finish the description of go statements: Go statements … When the function terminates, its goroutine also terminates. If the function has any return values, they are discarded when the function completes. go Server() go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c) Okay, so that bit about discarding return values makes sense, right? func main() { go sum(1, 3) // return value discarded } func sum(a, b int) int { return a + b } But what if you need that return value for something?