go中复数类型仅有complex64和complex128,声明需显式指定类型或用complex()函数;real()/imag()只读不可赋值;math/cmplx仅支持complex128,无隐式转换;复数相等比较按位进行,nan导致结果为false。

Go 里没有内置的 complex 类型关键字,只有两个预声明的复数类型:complex64 和 complex128,直接用就行,不用 import、不用定义。
怎么声明和初始化复数变量
Go 把复数当作基础数值类型处理,语法类似浮点数,但必须带虚部后缀(i)。不能写 z := 3 + 4i 然后指望编译器自动推导类型——它会报错 invalid operation: operator + not defined on complex(其实是类型推导失败,不是运算符问题)。
正确写法只有两种:
-
z := 3.0 + 4.0i→ 推导为complex128(因为字面量默认是float64) -
z := complex64(3) + 4i→ 显式转成complex64,注意4i这里会被隐式转为complex64,但3是整数,得先转
更稳妥的是用 complex 内置函数:z := complex(3.0, 4.0),它返回 complex128;complex(float32(3), float32(4)) 才得 complex64。
立即学习“go语言免费学习笔记(深入)”;
real() 和 imag() 函数只能读,不能赋值
这两个函数用来提取实部和虚部,返回值是对应精度的浮点数(real(z) 返回 float64 如果 z 是 complex128)。但它们不是左值,不能写 real(z) = 5 —— Go 不支持对函数调用结果赋值,会报 cannot assign to real(z)。
要修改复数的某一部分,只能重新构造:
- 改实部:
z = complex(5, imag(z)) - 改虚部:
z = complex(real(z), -2) - 想原地更新?不行。复数是值类型,所有操作都生成新值
math/cmplx 包里函数不接受 interface{},也不自动升阶
比如 cmplx.Sqrt(z) 要求 z 是 complex128;传 complex64 会编译失败:cannot use z (type complex64) as type complex128 in argument to cmplx.Sqrt。
没有隐式转换,也不能靠类型断言绕过。解决办法只有两个:
- 统一用
complex128(推荐,除非内存敏感) - 手动转换:
cmplx.Sqrt(complex128(z64)),但注意精度损失风险(complex64转complex128没问题,反过来才丢精度)
同理,cmplx.Pow、cmplx.Exp 等全部只认 complex128。
和 C/Python 复数行为差异最易踩坑的地方
Go 的复数不支持直接比较相等:z1 == z2 是合法的,但底层按位比——如果两个复数实部/虚部都是 NaN,== 会返回 false(因为 NaN != NaN),这点和浮点数一致,但容易被忽略。
另外,Go 没有复数格式化快捷方式:fmt.Printf("%v", z) 输出形如 (3+4i),但没法像 Python 那样用 f-string 控制小数位;得自己拆开 real(z) 和 imag(z) 格式化。
最后提醒:complex64 在 32 位系统上省内存,但在多数现代服务端场景中,用 complex128 更省心,避免反复转换和精度意外。










