Golang常量声明疑问:为何unsafe.Sizeof可用而binary.Size不可用?
Great question! Let's break this down step by step to understand the difference between these cases.
The core rule here is simple but strict in Go: Constant expressions must be evaluable entirely at compile time. Let's look at each scenario:
The Declarations That Work
1. const OK = uint64(0)
This is a straightforward type conversion applied to a numeric literal (0). Numeric literals are inherent compile-time constants, and converting them to a basic type like uint64 is an operation the Go compiler can resolve immediately during compilation. No runtime work is needed here, so this is totally valid.
2. const OK = int(unsafe.Sizeof(uint64(0)))
unsafe.Sizeof is a special built-in function, not a regular runtime function. The Go compiler evaluates it at compile time—it only cares about the type of its argument, not the actual value. Since uint64 has a fixed size (8 bytes on every system), the compiler can calculate this value without running your code. Wrapping that result in int() is another compile-time type conversion, so this works as a constant.
The Declaration That Fails: const NOK = binary.Size(uint64(0))
binary.Size is a standard library function that runs at runtime. Even though we know the serialized size of a uint64(0) is 8 bytes, this function doesn't just return a fixed value—it inspects the input's type and value dynamically when your program runs. The Go compiler can't guarantee that this function will always return a predictable, compile-time constant (its logic could handle different types or edge cases that only resolve at runtime).
Since Go requires constant initializers to be values the compiler can compute before the program starts, using a runtime function call like binary.Size here is invalid.
内容的提问来源于stack exchange,提问作者Gert Cuykens

