3 min read
Reminder! On Monday’s livestream, we’ll be Pair Programming on a real project. Don’t miss it! Channels are deceptively simple. They seem a bit magical. They feel like they do something. They feel like they send data around your system. But they really don’t. They’re just data types. They’re probably best thought of like Go’s array or slice type, with the limitation that you can only ever read the first value, and you can only ever set the last value.
Let’s talk about addresses. Address operators For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. This leads to one of my great annoyances about the Go language.
1 min read
Logical operators Logical operators apply to boolean values and yield a result of the same type as the operands. The left operand is evaluated, and then the right if the condition requires it. && conditional AND p && q is "if p then q else false" || conditional OR p || q is "if p then true else q" ! NOT !p is "not p" I think this is pretty intuitive.
Introducing Go 1.22!
Join me in less than an hour, when I’ll be live streaming again! I’ll be continuing to add SQLite support to Kivik, using Test-Driven Development. Go 1.22 was released on February 7. So I’m a bit behind on talking about the changes introduced to the spec. But better late than never! If you’re interested in my thoughts on some of the other changes, including those to the standard library, check out last week’s episode of the Cup o’ Go podcast.
Comparison operators, conclusion
Comparison operators … Slice, map, and function types are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier nil. Comparison of pointer, channel, and interface values to nil is also allowed and follows from the general rules above. Let’s demonstrate: var a func() var b int var c map[string]string fmt.Println(a == nil, b == nil, c == nil) // true, true, true But this only applies to a direct comparison with nil.
Comparison operators, part IV
Comparison operators … Struct types are comparable if all their field types are comparable. Two struct values are equal if their corresponding non-blank field values are equal. The fields are compared in source order, and comparison stops as soon as two field values differ (or all fields have been compared). I think this is clear. But it leads to some interesting things in the wild, when you want structs to not be comparable.
Comparison operators, part III
Today we continue through the list of data types and how comparison and ordering works on each. Comparison operators … Channel types are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil. Notice that channel comparison is effectively a comparison of identity. Not type or content. Two channels may have the same type and contents, but be unequal:
3 min read
Comparison operators, continued
Yesterday we started on comparison operators. Today we’ll continue, but there are a lot of types to cover, so I’ll break this down into a two or three parts, to keep each day’s email easily digestible. Recall that we had just been introduced to the concepts of ordered and comparable, and this is where we pick up… Comparison operators … These terms and the result of the comparisons are defined as follows:
I’ll be livestreaming again today! I hope you can join me as I continue where I left off last week, adding some new features to my open-source library, Kivik! Let’s talk about a mundane detail… that actually has some interesting nuances: Comparisons! Comparison operators Comparison operators compare two operands and yield an untyped boolean value. == equal != not equal < less <= less or equal > greater >= greater or equal In any comparison, the first operand must be assignable to the type of the second operand, or vice versa.
Today we’re looking at a deceptively short section of the spec: String concatenation… String concatenation Strings can be concatenated using the + operator or the += assignment operator: s := "hi" + string(c) s += " and good bye" String addition creates a new string by concatenating the operands. That’s it. Short, and sweet, eh? Except that it’s not quite so sweet, when you consider the implications of the last sentence: Every time you use + or += for a string, you create a new string.
Floating-point operators For floating-point and complex numbers, +x is the same as x, while -x is the negation of x. The result of a floating-point or complex division by zero is not specified beyond the IEEE-754 standard; whether a run-time panic occurs is implementation-specific. I find this to be quite interesting. An implementation may choose to panic, or not, if you attempt to divide a floating-point or complex number by zero.