2 min read
Close
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 more values will be sent on the channel. It is an error if ch is a receive-only channel. Sending to or closing a closed channel causes a run-time panic.
2 min read
Clear
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) clear(s) []T sets all elements up to the length of s to the zero value of T clear(t) type parameter see below clear is a relatively recent addition to Go, added just over a year ago.
3 min read
Copying slices
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 len(src) and len(dst). As a special case, if the destination’s core type is []byte, copy also accepts a source argument with core type bytestring.
2 min read
Beware of array reuse with append
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. That sounds pretty simple, doesn’t it? What’s to talk about? Well, this single sentence packs a lot of surprises. Consider this code: a := [.
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.
3 min read
Efficiently appending to slices
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 large underlying array that fits both the existing slice elements and the additional values. You may recall from our (much) earlier discussion about slices and backing arrays, that a slice has not only a length (the number of elements it contains), but also a capacity—essentially the number of available elements in the backing array.
2 min read
Appending to slices
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 variadic function append appends zero or more values x to a slice s and returns the resulting slice of the same type as s. The core type of s must be a slice of type []E.
1 min read
Built-in functions
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 like any other function but some of them accept a type instead of an expression as the first argument. The built-in functions do not have standard Go types, so they can only appear in call expressions; they cannot be used as function values.
2 min read
Modifying return values in deferred functions
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 finishing up the section on the defer keyword, with one special capability that it affords us. Defer statements …
3 min read
Defer execution order
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. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred. That is, if the surrounding function returns through an explicit return statement, deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller.
2 min read
Defer statements
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 returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.
1 min read
Fallthrough statements
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 straight forward. for x := range 10 { switch { case x%2 == 0: fmt.Print("X") fallthrough case x%3 == 0: fmt.Print("x") fallthrough case x%5 == 0: fmt.Print("O") } fmt.