23 min watch
Writing the perfect résumé to land your first Go job
I critique the résumé/CV of someone looking for their first Go job, and offer my suggestions for improvement.

1 min read
Type identity
Type identity Two types are either identical or different. Well now that’s profound, isn’t it? LOL. The real point is that there are not different “degrees of similarity.” The spec continues… A named type is always different from any other type. Otherwise, two types are identical if their underlying type literals are structurally equivalent; that is, they have the same literal structure and corresponding components have identical types. So the rules for type identity are rather simple.

3 min read
Core types
Yesterday we discussed underlying types. Today we’re looking at the somewhat more essoteric concept of a core type. The concept of a core type, as distinct (sometimes) from the underlying type exists for the benefit of some generics-related constructs. This will make more sense as we get to these uses of core types in the future. So for now we’re just going to breeze through the description, without diving into additional detail than what is provided in the spec.

2 min read
Underlying types
We’ve made it through the complete list of types in Go. Now we’re going to dig into some of the fundamentals, with a tour of general “Properties of types and values”. Properties of types and values Underlying types Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T’s underlying type is the underlying type of the type to which T refers in its declaration.
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
Channel synchronization
I’ve made the case that channels are just data types, and non-magical. So why should we care about channels, rather than just using some sort of slice, array, or custom first-in-first-out queue? The reason is that channels provide us certain guarantees with regard to synchronization. The spec explains: Channel types … A single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization.

1 min read
Closing channels
Channel types … A channel may be closed with the built-in function close. The multi-valued assignment form of the receive operator reports whether a received value was sent before the channel was closed. Closing a channel is a simple matter of using the built-in close function: // ch must be of type `chan T` or `chan<- T`. A receive-only channel (`<-chan T`) cannot be closed. close(ch) Calling close on a channel takes immediate effect, and prevents further values from being written to the channel (any items already in the channel may still be read).

2 min read
Creating channels
Channel types … A new, initialized channel value can be made using the built-in function make, which takes the channel type and an optional capacity as arguments: make(chan int, 100) Here we have the semi-magical make built-in function again. We’ve already seen it for use with arrays and slices. Consider this yet another clue that a channel is just another type, similar to array and slice, in that it “just” holds a bunch of values, and isn’t magical in any way.

2 min read
Directional channels
Channel types … The optional <- operator specifies the channel direction, send or receive. If a direction is given, the channel is directional, otherwise it is bidirectional. A channel may be constrained only to send or only to receive by assignment or explicit conversion. chan T // can be used to send and receive values of type T chan<- float64 // can only be used to send float64s <-chan int // can only be used to receive ints When you create a new channel, you get a bidirectional channel.

1 min read
Channel types
Channel types A channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil. ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType . Channels are one of the most confusing parts of Go, for many newcomers. But they don’t need to be. They’re actually quite simple. Think of a channel as an array, which can only be read from one end, and appended to the other.

2 min read
Map length and capacity
Maps, like arrays and slices, have length. Map types … The number of map elements is called its length. For a map m, it can be discovered using the built-in function len and may change during execution. … This should be straight forward, but let’s consider a couple examples for good measure: x := map[string]int{"a": 1, "b": 2, "c": 3} fmt.Println(len(x)) // 3 var y map[string]float64 fmt.Println(len(y)) // 0 And somewhat deceptively, their capacity can also be set, or at least hinted at, but not read.

2 min read
Using maps
Today I’m jumping around a bit, for the sake of coherence. Map types … [Map] elements may be added during execution using assignments and retrieved with index expressions; they may be removed with the delete built-in function. A new, empty map value is made using the built-in function make, … Let’s summarize with examples. We’ll dive into details as the relevant portions of the spec come up. To create a map, you use the built-in function make: