Package unsafe … The function Offsetof takes a (possibly parenthesized) selector s.f, denoting a field f of the struct denoted by s or *s, and returns the field offset in bytes relative to the struct’s address. If f is an embedded field, it must be reachable without pointer indir … | Continue reading
Package unsafe … The functions Alignof and Sizeof take an expression x of any type and return the alignment or size, respectively, of a hypothetical variable v as if v was declared via var v = x. Grammar nit! That should be “…as if v were…” But nobody cares about that. While Alig … | Continue reading
Today we’re venturing into dangerous territory… the unsafe package! You can go years working in Go (as I have) without ever using unsafe, or just barely bumping into it. On the other hand, somd developers spend significant time using unsafe, to get the utmost performance out of t … | Continue reading
Run-time panics Execution errors such as attempting to index an array out of bounds trigger a run-time panic equivalent to a call of the built-in function panic with a value of the implementation-defined interface type runtime.Error. That type satisfies the predeclared interface … | Continue reading
Today we’re looking at errors, and the built-in error interface. For a concept that’s so central to the Go ethos, the spec has surprisingly little to say about it: Errors The predeclared type error is defined as type error interface { Error() string } It is the conventional inter … | Continue reading
Program execution A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. The main package must have package name main and declare a function main that takes no arguments and returns no value. f … | Continue reading
I’ve been on an unannounced, unplanned, month-long hiatus, what with moving my family across the globe. But with the new year starting, and the worst of the chaos behind me, I’m going to try to get back in the saddle again, and pick up where I left off. And what better way to ini … | Continue reading
I wasn’t exactly planning to take last week off from the daily emails, but with Thanksgiving preparations, and still living out of a suitcase, it just happened that way. But I’m back now, and ready to talk about Program initialization Program initialization The packages of a comp … | Continue reading
We’ve been looking at the order of package variable initialization. What if these rules are confusing? Or even non-desterministic for you? Or maybe you simply want to do something more advanced than is feasible in package variable declarations. Is there an alternative? There is! … | Continue reading
We’re nearing the end of the discussion on package initialization order. Monday should be the last day on that topic, but more on that shortly. Up to now, we’ve been looking at the deterministic order-of-initialization rules.Today’s topic is when that order is not defined. Packag … | Continue reading
Today’s section of the spec is a bit dense and technical. But don’t worry, it makes a lot of sense once we get to the end. Package initialization … Dependency analysis does not rely on the actual values of the variables, only on lexical references to them in the source, analyzed … | Continue reading
Package initialization … The declaration order of variables declared in multiple files is determined by the order in which the files are presented to the compiler: Variables declared in the first file are declared before any of the variables declared in the second file, and so on … | Continue reading
Thank you to everyone who responded to yesterday’s pop quiz! I got a number of responses, both by email, and on LinkedIn and Mastodon. And the majority of responses made the exact same mistake I made, and assumed the code was invalid, because a is referenced before it’s initializ … | Continue reading
It’s time for a pop quiz. Is the following code valid? var x = a var a = 3 Think about it. Hit reply with your answer, and explanation. I’ll provide a full answer and explanation tomorrow. Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 202 … | Continue reading
I’m sorry for missing a couple days. We took an long weekend with some extended family to visit the beach here in Guatemala. But I’m back, and ready to talk about … zero values! Program initialization and execution The zero value When storage is allocated for a variable, either t … | Continue reading
Today we have something a bit different. Just a sample package. An example package Here is a complete Go package that implements a concurrent prime sieve. package main import "fmt" // Send the sequence 2, 3, 4, … to channel 'ch'. func generate(ch chan<- int) { for i := 2; ; i++ { … | Continue reading
Yesterday I promised to teach you the one dirty trick they don’t want you to know about, to get around Go’s restriction on circular imports. It’s explained in this sentence, the last from the spec on the topic of imports. Import declarations … To import a package solely for its s … | Continue reading
First off, the spec provides an example of how to reference a symbol in an imported package, using different import alias options. I’ve already provided my own examples earlier, and it’s pretty straight forward, so we’ll just breeze through this part. Import declarations … Consid … | Continue reading
Today we’re looking at one of the more essoteric parts of the spec. Import declarations … Implementation restriction: A compiler may restrict ImportPaths to non-empty strings using only characters belonging to Unicode’s L, M, N, P, and S general categories (the Graphic characters … | Continue reading
Newcomers to Go often try to use relative imports, and then are usually bitten by random weird problems. They seem to work sometimes, and not other times. What’s the deal? import "./foo" Import declarations … The interpretation of the ImportPath is implementation-dependent but it … | Continue reading
We’re continuing today our discussion of imports. Yesterday we left off with using explicit package names in an import clause when the package name differs from the last element of the import path. Is that the only reason to explicitly name your imports? No. Sometimes you need to … | Continue reading
Today we have a very important topic… Import declarations An import declaration states that the source file containing the declaration depends on functionality of the imported package (§Program initialization and execution) and enables access to exported identifiers of that packa … | Continue reading
I’m back! I took an extra week off, from what I planned, due to chaotic circumstances, but I’m back again now. I’m also in a new timezone—America/Central. So my daily emails may begin coming on a different erratic schedule than the previous erratic schedule you were accustomed to … | Continue reading
A quick note to say that I’m taking next week off, for a move. I expect to return October 4 with more Boldy Go: Daily emails. Until then! We’re down to the final two built-in functions in Go. And these are probably functions you should not be using, except possibly in throw-away … | Continue reading
Handling panics … The return value of recover is nil when the goroutine is not panicking or recover was not called directly by a deferred function. Conversely, if a goroutine is panicking and recover was called directly by a deferred function, the return value of recover is guara … | Continue reading
Yesterday we saw how panic plays with deferred functions, in terms of order of execution. Today we’ll take things up one level, and throw recover in there… there’s more to recover than just execution order. We’ll get to that next. Handling panics … The recover function allows a p … | Continue reading
Handling panics … While executing a function F, an explicit call to panic or a run-time panic terminates the execution of F. Any functions deferred by F are then executed as usual. Next, any deferred functions run by F’s caller are run, and so on up to any deferred by the top-lev … | Continue reading
We’re ready for the section of the Go spec that talks about panic and recover, Go’s rough analogs to throw and catch. Handling panics Two built-in functions, panic and recover, assist in reporting and handling run-time panics and program-defined error conditions. func panic(inter … | Continue reading
Today’s topic: Allocation! What? You thought allocation was relegated to languages like C and C++? Yeah, that’s actually pretty close to true. We’re not learning about malloc today. Rather, we’re learning about the built-in function new, which gives us just one (of many!) ways to … | Continue reading
Today’s topic: Allocation! What? You thought allocation was relegated to languages like C and C++? Yeah, that’s actually pretty close to true. We’re not learning about malloc today. Rather, we’re learning about the built-in function new, which gives us just one (of many!) ways to … | Continue reading
I always try to add my own commentary, examples, or other explanation in these emails. Today I’m not really sure what to add. min and max are such basic, and self-evident features, that the biggest surprise about these is that they’re such recent additions to the language. They w … | Continue reading
Making slices, maps and channels The built-in function make takes a type T, optionally followed by a type-specific list of expressions. The core type of T must be a slice, map or channel. It returns a value of type T (not *T). The memory is initialized as described in the section … | Continue reading
A few of the built-in functions are very special, in that they can evaluate to constant expressions. len and cap are two such functions. But they aren’t always evaluated to constant expressions, sometimes they’re more normal-ish runtime functions. Length and capacity … The expres … | Continue reading
Length and capacity … The capacity of a slice is the number of elements for which there is space allocated in the underlying array. At any time the following relationship holds: 0 <= len(s) <= cap(s) Recall that a slice is backed by a fixed-length array, which may have more eleme … | Continue reading
Length and capacity The built-in functions len and cap take arguments of various types and return a result of type int. The implementation guarantees that the result always fits into an int. Recall that int is either a 32- or 64-bit integer. So this means that the theoretical max … | Continue reading
Deletion of map elements The built-in function delete removes the element with key k from a map m. The value k must be assignable to the key type of m. delete(m, k) // remove element m[k] from map m We already looked at clear, which deletes everything in a map. delete lets you su … | Continue reading
Today we’re looking at what are almost certainly the least used built-in functions in Go. This is why I’m covering it all in a single day, even though there’s enough material here to potentially justify two or three. Manipulating complex numbers Three functions assemble and disas … | Continue reading
Today we’re looking at the close built-in function. There’s not really any new information here, as we’ve already talked about channels, but it’s a good opportunity to review. Close For an argument ch with a core type that is a channel, the built-in function close records that no … | Continue reading
Clear The built-in function clear takes an argument of map, slice, or type parameter type, and deletes or zeroes out all elements [[Go 1.21(https://go.dev/ref/spec#Go_1.21)]]. Call Argument type Result clear(m) map[K]T deletes all entries, resulting in an empty map (len(m) == 0) … | Continue reading
Appending to and copying slices … The function copy copies slice elements from a source src to a destination dst and returns the number of elements copied. The core types of both arguments must be slices with identical element type. The number of elements copied is the minimum of … | Continue reading
On Friday we looked at what happens when appending to a slice exceeds the capacity of the backing array. Today we’ll consider the alternative: What if the backing array can hold the new values? Appending to and copying slices … Otherwise, append re-uses the underlying array. Okay … | Continue reading
Yesterday we were introduced to the append function, which on the surface seems quite straight forward. But there are nuänces and gotchas! Appending to and copying slices … If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently … | Continue reading
Appending to and copying slices The built-in functions append and copy assist in common slice operations. For both functions, the result is independent of whether the memory referenced by the arguments overlaps. Today and tomorrow we’ll look at the first of those two, append: The … | Continue reading
We’ve just finished up the rather long section on different types of statements. There’s only a few more sections in the spec, before we finish this series. And today we start looking at Built-in functions! Built-in functions Built-in functions are predeclared. They are called li … | Continue reading
Oops! It seems that Friday’s email got stuck, and didn’t actually send until late Monday. Meaning you probably got two emails in the same day, and out of order. I hope it didn’t bother anyone too much. I should probably make a joke about how it was deferred… Nah! Today we’ll be f … | Continue reading
Let’s talk about some of the nuance surrounding defer that’s often lost, or simply forgotten. Defer statements … Each time a “defer” statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Ins … | Continue reading
We’re at the last item in the “Statements” section of the spec, before we move on to built-in functions. And naturally, the last one is… the defer statement~ Defer statements A “defer” statement invokes a function whose execution is deferred to the moment the surrounding function … | Continue reading
Fallthrough statements A “fallthrough” statement transfers control to the first statement of the next case clause in an expression “switch” statement. It may be used only as the final non-empty statement in such a clause. FallthroughStmt = "fallthrough" . Well that’s pretty strai … | Continue reading