...
This commit is contained in:
30
specs.md
30
specs.md
@@ -370,6 +370,36 @@ Arena :: struct {
|
||||
allocators : [2]Allocator = .[xx gpa, xx arena]; // protocol values in array
|
||||
```
|
||||
|
||||
#### Ownership and Lifetime
|
||||
|
||||
Protocol values have two ownership modes depending on how they are created:
|
||||
|
||||
| Conversion | `ctx` points to | Lifetime | Who frees |
|
||||
|------------|----------------|----------|-----------|
|
||||
| `xx value` | Heap-allocated copy | Until `free(p)` | Caller |
|
||||
| `xx @ptr` | Original pointee | Tied to pointee | Caller manages pointee |
|
||||
|
||||
**`xx value`** — the concrete data is heap-copied so the protocol value is self-contained.
|
||||
It can be stored in containers, returned from functions, and outlives the scope where it was created.
|
||||
Call `free(p)` to release the backing memory when done:
|
||||
```sx
|
||||
s : Sizable = xx Widget.{ value = 42 }; // heap-copies Widget
|
||||
print("{}\n", s.size());
|
||||
free(s); // frees the heap-allocated Widget copy
|
||||
```
|
||||
|
||||
**`xx @ptr`** — the protocol borrows the pointer. The protocol value is only valid as long as
|
||||
the pointee is alive. Mutations through the protocol are visible through the original pointer:
|
||||
```sx
|
||||
w := Widget.{ value = 0 };
|
||||
s : Sizable = xx @w; // borrows &w
|
||||
s.add(5); // modifies w through ctx
|
||||
print("{}\n", w.value); // 5
|
||||
// do NOT free(s) — w owns the data
|
||||
```
|
||||
|
||||
**Vtables** are global constants — shared across all protocol values of the same `(Protocol, ConcreteType)` pair. They are never allocated or freed at runtime.
|
||||
|
||||
#### Default Methods
|
||||
Protocol methods can have bodies. `self` dispatches through the vtable (dynamic dispatch):
|
||||
```sx
|
||||
|
||||
Reference in New Issue
Block a user