Comparison operators, continued

February 13, 2024

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:

  • Boolean types are comparable. Two boolean values are equal if they are either both true or both false.

Recall from yesterday that in contrast to many other languages, Boolean values are not ordered in Go.

  • Integer types are comparable and ordered. Two integer values are compared in the usual way.

LOL. The “usual way”. I love it when the spec occasionally “breaks character” and uses normal language like this.

Floating-point types are comparable and ordered. Two floating-point values are compared as defined by the IEEE-754 standard.

Consult IEEE-754 if you really care where this differs from “the usual way”. You probably don’t.

  • Complex types are comparable. Two complex values u and v are equal if both real(u) == real(v) and imag(u) == imag(v).

I’d be surprised if you ever use a complex number in Go, so you probably won’t care about how they compare, either.

  • String types are comparable and ordered. Two string values are compared lexically byte-wise.

This is probably intuitive. abc and abd are not equal, and the former is ordered before the latter. One thing to note: Sorting strings this way (bytewise, that is) isn’t always the preferred sorting approach. Many languages, or even different locales with the same language, have different ordering rules (i.e. does uppercase or lowercase come first, or are they intermingled?) If you’re sorting human text (say names, or titles of books), particularly in non-English languages, you’d do well to look into one of the i18n-related packages for smarter sorting.

  • Pointer types are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.

Two things to note here:

  1. Pointers in Go, unlike in languages like C, are not ordered.
  2. Some types in Go have zero size. Two common examples: struct{} and a zero-length array (i.e. [0]int). These types are handy in that they take up no memory, but this also means that the implementation is free to have all zero-size variables consume the same (zero-length) memory address. This means you cannot reliably compare different instances of zero-lenght values:
var x = struct{}{}
var y = struct{}{}
if x == y { // Technically, it's undefined whether this will be true or false
	fmt.Println("same")
}

Quotes from [_The Go Programming Language Specification_](https://go.dev/ref/spec) Version of August 2, 2023

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Conversions between numeric types

So we’ve gone through the high-level conversion stuff… now we dive into some particulars. Today, numeric conversions. Conversions between numeric types For the conversion of non-constant numeric values, the following rules apply: When converting between integer types, if the value is a signed integer, it is sign extended to implicit infinite precision; otherwise it is zero extended. It is then truncated to fit in the result type’s size. For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0.


Manipulating complex numbers

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 disassemble complex numbers. The built-in function complex constructs a complex value from a floating-point real and imaginary part, while real and imag extract the real and imaginary parts of a complex value.


Order of evaluation and floating point numbers

Today I’ll be live streaming again! This time, picking up where we left off last week, and adding another feature to my new Go code rewriter and simplifier. Join me! Order of Evaluation … Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation by overriding the default associativity. In the expression x + (y + z) the addition y + z is performed before adding x.

Get daily content like this in your inbox!

Subscribe