Updated Destructors, 2nd edition (rest)
This commit is contained in:
parent
bba61c0452
commit
4cea3467cb
|
@ -2,7 +2,6 @@
|
|||
Nim Destructors and Move Semantics
|
||||
==================================
|
||||
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
|
@ -395,6 +394,50 @@ Cursor variables are commonly used in ``iterator`` implementations:
|
|||
yield it
|
||||
|
||||
|
||||
Lent type
|
||||
=========
|
||||
|
||||
``proc p(x: sink T)`` means that the proc ``p`` takes ownership of ``x``.
|
||||
To eliminate even more creation/copy <-> destruction pairs, a proc's return
|
||||
type can be annotated as ``lent T``. This is useful for "getter" accessors
|
||||
that seek to allow an immutable view into a container.
|
||||
|
||||
The ``sink`` and ``lent`` annotations allow us to remove most (if not all)
|
||||
superfluous copies and destructions.
|
||||
|
||||
``lent T`` is like ``var T`` a hidden pointer. It is proven by the compiler
|
||||
that the pointer does not outlive its origin. No destructor call is injected
|
||||
for expressions of type ``lent T`` or of type ``var T``.
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
Tree = object
|
||||
kids: seq[Tree]
|
||||
|
||||
proc construct(kids: sink seq[Tree]): Tree =
|
||||
result = Tree(kids: kids)
|
||||
# converted into:
|
||||
`=sink`(result.kids, kids)
|
||||
|
||||
proc `[]`*(x: Tree; i: int): lent Tree =
|
||||
result = x.kids[i]
|
||||
# borrows from 'x', this is transformed into:
|
||||
result = addr x.kids[i]
|
||||
# This means 'lent' is like 'var T' a hidden pointer.
|
||||
# Unlike 'var' this cannot be used to mutate the object.
|
||||
|
||||
iterator children*(t: Tree): lent Tree =
|
||||
for x in t.kids: yield x
|
||||
|
||||
proc main =
|
||||
# everything turned into moves:
|
||||
let t = construct(@[construct(@[]), construct(@[])])
|
||||
echo t[0] # accessor does not copy the element!
|
||||
|
||||
|
||||
|
||||
Owned refs
|
||||
==========
|
||||
|
||||
|
|
Loading…
Reference in New Issue