We’ve finished the discussion of the new range-over-func feature, so let’s continue where we left off before the Go 1.23 release, with a feature you’ll rarely, if ever, use. Goto statements A “goto” statement transfers control to the statement with the corresponding label within … | Continue reading
We’ve been looking at Go 1.23’s new range-over-func feature. And we’re just about through what the spec has to say about it. Except for one thing. The example code! // iteration support for a recursive tree data structure type Tree[K cmp.Ordered, V any] struct { left, right *Tree … | Continue reading
For statements with range clause … For a function f, the iteration proceeds by calling f with a new, synthesized yield function as its argument. Let’s talk about yeild today. If I’m honest, this was probably the scariest part of these new function iterators, before I started actu … | Continue reading
As mentioned yesterday, today we’re taking a bit of a step back to an earlier portion of the spec, which was just updated. Here’s the first part of the updated section of the spec (new additions emphasized): For statements with range clause A “for” statement with a “range” clause … | Continue reading
I missed the last couple of days. Oops! It’s a busy time here, as I’m preparing for an international move, and balancing a new business venture I’m working on. But I’m back today! The big news in the Go world is that on Tuesday, Go 1.23.0 was released! What this means for us, as … | Continue reading
Let’s continue… haha See what I did there? Bleh, okay. Continue statements A “continue” statement begins the next iteration of the innermost enclosing “for” loop by advancing control to the end of the loop block. The “for” loop must be within the same function. ContinueStmt = "co … | Continue reading
Break statements … If there is a label, it must be that of an enclosing “for”, “switch”, or “select” statement, and that is the one whose execution terminates. In other words, you can’t break to a label that labels a more deeply nested for, switch or select statement, or to one t … | Continue reading
Return statements A “break” statement terminates execution of the innermost “for”, “switch”, or “select” statement within the same function. BreakStmt = "break" [ Label ] . We’ll discuss the Label mentioned tomorrow. Until then, the key word here is innermost. This shouldn’t be v … | Continue reading
Just a couple small notes before we move on from return statements… Return statements … Regardless of how they are declared, all the result values are initialized to the zero values for their type upon entry to the function. A “return” statement that specifies results sets the re … | Continue reading
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) … | Continue reading
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-va … | Continue reading
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 … | Continue reading
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 funct … | Continue reading
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 stateme … | Continue reading
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 stateme … | Continue reading
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 getAChann … | Continue reading
I'll be live streaming again today! Today I'll be setting up GitHub Actions for a Go project. So come with your CI/CD questions! [See you there!](https://www.youtube.com/watch?v=RM6DfN1CKkE) Select statements … If one or more of the communications can proceed, a single one that c … | Continue reading
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 … | Continue reading
Exactly a year ago (yesterday), Russ Cox submitted a proposal to add two new range capabilities to Go: range-over-int, and range-over-func. The former was added to Go 1.22. And the latter left me immediately skeptical. I spent a fair amount of time (as measured in Internet minute … | Continue reading
I’m taking a detour from the Go spec today, to share my experience with the new range-over-func feature coming in Go 1.23: Exactly a year ago (yesterday), Russ Cox submitted a proposal to add two new range capabilities to Go: range-over-int, and range-over-func. The former was ad … | Continue reading
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 ca … | Continue reading
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 … | Continue reading
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 … | Continue reading
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 th … | Continue reading
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 th … | Continue reading
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 … | Continue reading
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 … | Continue reading
Today we finish up with some final notes, and a big example, from the spec section on for statements. For statements with range clause … If the iteration variables are not explicitly declared by the “range” clause, they must be preexisting. In this case, the iteration values are … | Continue reading
For statements with range clause … The iteration variables may be declared by the “range” clause using a form of short variable declaration (:=). In this case their scope is the block of the “for” statement and each iteration has its own new variables [Go 1.22] (see also “for” st … | Continue reading
I’m back from my holiday! I thought I’d send at least a few dalies over the last week while I was on vacation, but it wasn’t meant to be. But now that I’m back, we’ll pick up where we left off… For statements with range clause … For an integer value n, the iteration values 0 thro … | Continue reading
Two quick related notes: I missed a day or two last week, due to travel. I’lll be traveling through the middle of next week as well, so these “daily” emails may be slightly less frequent. We’ll see. And related to that, no live stream this week or next. I expect to live stream ag … | Continue reading
For statements with range clause … The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If a map entry that has not yet been reached is removed during iteration, the corresponding iteration value will not be produced. … | Continue reading
For statements with range clause … For a string value, the “range” clause iterates over the Unicode code points in the string starting at byte index 0. On successive iterations, the index value will be the index of the first byte of successive UTF-8-encoded code points in the str … | Continue reading
For statements with range clause … For an array, pointer to array, or slice value a, the index iteration values are produced in increasing order, starting at element index 0. If at most one iteration variable is present, the range loop produces iteration values from 0 up to len(a … | Continue reading
For statements with range clause … For each iteration, iteration values are produced as follows if the respective iteration variables are present: Range expression 1st value 2nd value array or slice a [n]E, *[n]E, or []E index i int a[i] E string s string type index i int see bel … | Continue reading
For statements with range clause … Function calls on the left are evaluated once per iteration. This small sentence is easy to overlook. What does it mean? It means if you have any function calls on the left hand side of the for range statement, they are executed per iteration. W … | Continue reading
For statements with range clause … The range expression x is evaluated once before beginning the loop, with one exception: if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated. The first part of this seems pretty self-evident, … | Continue reading
Yesterday we saw some high-level examples of range statements. Let’s start into some of the details now. For statements with range clause … For each entry it assigns iteration values to corresponding iteration variables if present and then executes the block. RangeClause = [ Expr … | Continue reading
For statements with range clause A “for” statement with a “range” clause iterates through all entries of an array, slice, string or map, values received on a channel, or integer values from zero to an upper limit [Go 1.22]. Wow, that’s a long list. And it’s about to get longer! G … | Continue reading
For statements with for clause … The variable used by the first iteration is declared by the init statement. The variable used by each subsequent iteration is declared implicitly before executing the post statement and initialized to the value of the previous iteration’s variable … | Continue reading
For statements with for clause … The variable used by the first iteration is declared by the init statement. The variable used by each subsequent iteration is declared implicitly before executing the post statement and initialized to the value of the previous iteration’s variable … | Continue reading
If you haven't joined me for a livestream in the past, consider [joining today](https://youtube.com/live/BYOsoZ5ywx8)! I'll be doing some refactoring, and adding new features to [Kivik](https://kivik.io/), with TDD. For statements with for clause … Each iteration has its own sepa … | Continue reading
For statements with for clause … Any element of the ForClause may be empty but the semicolons are required unless there is only a condition. If the condition is absent, it is equivalent to the boolean value true. for cond { S() } is the same as for ; cond ; { S() } for { S() } is … | Continue reading
Today we’ll look at the second, of three, types of for statements: Those with a for clause. For statements with for clause A “for” statement with a ForClause is also controlled by its condition, but additionally it may specify an init and a post statement, such as an assignment, … | Continue reading
Go is known as a simple language, with straightforward concepts. For loops may be one of rare exceptions to that straightforward character, with three different forms: For statements A “for” statement specifies repeated execution of a block. There are three forms: The iteration m … | Continue reading
Two final items with regard to type switches, before we move on to the next topic: Type switches … The type switch guard may be preceded by a simple statement, which executes before the guard is evaluated. This is pretty straight forward. It works just like the simple statements … | Continue reading
More live coding today! Join me! And bring your questions. Type switches … A type parameter or a generic type may be used as a type in a case. If upon instantiation that type turns out to duplicate another entry in the switch, the first matching case is chosen. func f[P any](x an … | Continue reading
We’ve been looking at type switches since last week. Today the spec shows us a large example, comparing type switches to the equivalent expressed without them. Type switches … Given an expression x of type interface{}, the following type switch: switch i := x.(type) { case nil: p … | Continue reading