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
complexconstructs a complex value from a floating-point real and imaginary part, whilerealandimagextract the real and imaginary parts of a complex value.complex(realPart, imaginaryPart floatT) complexT real(complexT) floatT imag(complexT) floatTThe type of the arguments and return value correspond. For
complex, the two arguments must be of the same floating-point type and the return type is the complex type with the corresponding floating-point constituents:complex64forfloat32arguments, andcomplex128forfloat64arguments. If one of the arguments evaluates to an untyped constant, it is first implicitly converted to the type of the other argument. If both arguments evaluate to untyped constants, they must be non-complex numbers or their imaginary parts must be zero, and the return value of the function is an untyped complex constant.
The spec provides examples of this, too, which we’ll see shortly. But since this untyped constant stuff is probably the most confusing part of this (aside from the inherently confusing nature of complex numbers), here are a few extra examples to spell it out:
x := complex(1, 2) // x is of type complex128
const y = complex(1, 2) // y is an untyped complex constant
z := complex(float32(1), 2) // z is of type complex64
For
realandimag, the argument must be of complex type, and the return type is the corresponding floating-point type:float32for acomplex64argument, andfloat64for acomplex128argument. If the argument evaluates to an untyped constant, it must be a number, and the return value of the function is an untyped floating-point constant.
So naturally, you cannot call real or imag on a non-numeric untyped constant.
real("string") // Nuh-huh
imag(false) // Nope!
The
realandimagfunctions together form the inverse ofcomplex, so for a valuezof a complex typeZ,z == Z(complex(real(z), imag(z))).If the operands of these functions are all constants, the return value is a constant.
var a = complex(2, -2) // complex128 const b = complex(1.0, -1.4) // untyped complex constant 1 - 1.4i x := float32(math.Cos(math.Pi/2)) // float32 var c64 = complex(5, -x) // complex64 var s int = complex(1, 0) // untyped complex constant 1 + 0i can be converted to int _ = complex(1, 2<<s) // illegal: 2 assumes floating-point type, cannot shift var rl = real(c64) // float32 var im = imag(a) // float64 const c = imag(b) // untyped constant -1.4Arguments of type parameter type are not permitted.
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)