2 min read
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.
1 min read
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.
3 min read
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.
2 min read
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.
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.
2 min read
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.
2 min read
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.
2 min read
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" .
2 min read
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?
2 min read
Go statements, continued
Now that we’ve talked about what goroutines are and aren’t, lets look at the details of a Go statement: Go statements … The expression must be a function or method call; it cannot be parenthesized. This is important! The expression must be a functino or method call. Not simply the name of a function or method. That is to say, this: go foo() not that: go foo This may feel pretty natural, but it’s easy (at leat for me) to forget sometimes.
2 min read
Go statements
At long last, we’re ready to learn about Go’s namesake feature! Go statements A “go” statement starts the execution of a function call as an independent concurrent thread of control, or goroutine, within the same address space. GoStmt = "go" Expression . Now before we talk about the particulars of how a go statement works, I want to set aside a common misconception, that’s subtly addressed in the above description.
2 min read
What good are nil channels?
I’ll be live streaming again today! But this time it’s a bit different. I found a bug in the Go standard library! 😲 So on today’s live stream, I’ll be coming up with a minimal reproducible case, and filing a bug report. And hopefully also submitting a patch to fix the bug! Join me I recently asked you if you knew of any practical uses of a nil channel in Go.