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, whilereal
andimag
extract the real and imaginary parts of a complex value.complex(realPart, imaginaryPart floatT) complexT real(complexT) floatT imag(complexT) floatT
The 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:complex64
forfloat32
arguments, andcomplex128
forfloat64
arguments. 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
real
andimag
, the argument must be of complex type, and the return type is the corresponding floating-point type:float32
for acomplex64
argument, andfloat64
for acomplex128
argument. 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
real
andimag
functions together form the inverse ofcomplex
, so for a valuez
of 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.4
Arguments of type parameter type are not permitted.
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)