Type bound operators
A type bound operator is a proc or func whose name starts with \= but isn’t an operator (i.e. containing only symbols, such as \==). These are unrelated to setters (see Properties), which instead end in \=. A type bound operator declared for a type applies to the type regardless of whether the operator is in scope (including if it is private).
# foo.nim:
var witness* = 0
type Foo[T] = object
proc initFoo*(T: typedesc): Foo[T] = discard
proc `=destroy`[T](x: var Foo[T]) = witness.inc # type bound operator
# main.nim:
import foo
block:
var a = initFoo(int)
doAssert witness == 0
doAssert witness == 1
block:
var a = initFoo(int)
doAssert witness == 1
`=destroy`(a) # can be called explicitly, even without being in scope
doAssert witness == 2
# will still be called upon exiting scope
doAssert witness == 3
Type bound operators are: \=destroy, \=copy, \=sink, \=trace, \=deepcopy, \=wasMoved, \=dup.
These operations can be overridden instead of overloaded. This means that the implementation is automatically lifted to structured types. For instance, if the type T has an overridden assignment operator \=, this operator is also used for assignments of the type seq[T].
Since these operations are bound to a type, they have to be bound to a nominal type for reasons of simplicity of implementation; this means an overridden deepCopy for ref T is really bound to T and not to ref T. This also means that one cannot override deepCopy for both ptr T and ref T at the same time, instead a distinct or object helper type has to be used for one pointer type.
For more details on some of those procs, see Lifetime-tracking hooks.