Use Values for Null Safety
I'm trying to understand the idiomatic Go approach for expressing non-nullability.
As I understand it:
- A struct value can never be
nil. - A pointer (
*T) can benil, so it's commonly used when the absence of a value is meaningful.
For example:
type User struct {
Name string
}
// User can never be nil.
func ProcessValue(user User) {
// ...
}
// User may be nil.
func ProcessPointer(user *User) {
// ...
}
The problem is that using a value has two different semantics:
- It guarantees the argument is non-nil.
- It copies the entire struct when passed to a function or assigned.
For small structs this isn't a concern, but for very large structs the copy can be expensive. In those cases I'd prefer to pass a pointer, but then I've lost the compile-time guarantee that the value isn't nil.
For example:
type LargeStruct struct {
Data [1024 * 1024]byte
}
func Process(s LargeStruct) {
// Copies the entire struct.
}
Is there an idiomatic way in Go to express "this must never be nil" while still passing a pointer?
Or is the accepted Go approach simply to use *T and rely on documentation and runtime checks when non-nil is required?