ref object
types [language.refobject]
Avoid ref object
types, except:
- for "handle" types that manage a resource and thus break under value semantics
- where shared ownership is intended
- in reference-based data structures (trees, linked lists)
- where a stable pointer is needed for 3rd-party compatibility
Prefer explicit ref MyType
where reference semantics are needed, allowing the caller to choose where possible.
# prefer explicit ref modifiers at usage site
func f(v: ref Xxx) = discard
let x: ref Xxx = new Xxx
# Consider using Hungarian naming convention with `ref object` - this makes it clear at usage sites that the type follows the unusual `ref` semantics
type XxxRef = ref object
# ...
Pros
ref object
types useful to prevent unintended copies- Limits risk of accidental stack allocation for large types
- This commonly may lead to stack overflow, specially when RVO is missed
- Garbage collector simplifies some algorithms
Cons
ref object
types have surprising semantics - the meaning of basic operations like=
changes- Shared ownership leads to resource leaks and data races
nil
references cause runtime crashes- Semantic differences not visible at usage site
- Always mutable - no way to express immutability
- Cannot be stack-allocated
- Hard to emulate value semantics
Notes
XxxRef = ref object
is a syntactic shortcut that hides the more explicit ref Xxx
where the type is used - by explicitly spelling out ref
, readers of the code become aware of the alternative reference / shared ownership semantics, which generally allows a deeper understanding of the code without having to look up the type declaration.