Skip to content

Pointer

Chung Leong edited this page Apr 11, 2024 · 7 revisions

A pointer is a variable that points to other variables. It holds a memory address. It also holds a length if it's a slice pointer.

Auto-deferenecing

Zigar auto-deferences a pointer when you perform a property lookup:

const std = @import("std");

pub const StructA = struct {
    number1: i32,
    number2: i32,

    pub fn print(self: StructA) void {
        std.debug.print("{any}\n", .{self});
    }
};

pub const StructB = struct {
    child: StructA,
    pointer: *StructA,
};

pub var a: StructA = .{ .number1 = 1, .number2 = 2 };
pub var b: StructB = .{
    .child = .{ .number1 = -1, .number2 = -2 },
    .pointer = &a,
};
import module from './pointer-example-1.zig';

console.log(module.b.child.number1, module.b.child.number2);
console.log(module.b.pointer.number1, module.b.pointer.number2);

In the example above, child is a struct in StructB itself while pointer points to a struct sitting outside. The manner of access is the same. Assignment works the same way:

import module from './pointer-example-1.zig';

module.b.child.number1 = -123;
module.b.pointer.number1 = 123;
module.b.child.print();
module.b.pointer.print();
module.a.print();

Notice how a has been modified through the pointer.

Auto-vivification

Assignment to a pointer changes its target:

import module from './pointer-example-1.zig';

module.b.child = { number1: -123, number2: -456 };
module.b.pointer = { number1: 123, number2: 456 };
module.b.child.print();
module.b.pointer.print();
module.a.print();
pointer-example-1.StructA{ .number1 = -123, .number2 = -456 }
pointer-example-1.StructA{ .number1 = 123, .number2 = 456 }
pointer-example-1.StructA{ .number1 = 1, .number2 = 2 }

While the assignment to child altered the struct, the assignment to pointer actually changed its target to a new instance of StructA, created automatically by Zigar when it detected that the object given isn't an instance of StructA.

Explicitly dereferencing

In order to modify the target of a pointer as a whole, you'd need to explicitly deference the pointer:

import module from './pointer-example-1.zig';

module.b.pointer['*'] = { number1: 123, number2: 456 };
module.a.print();

The above code is equivalent to the following Zig code:

b.pointer.* = .{ .number1 = 123, .number2 = 456 };
a.print();

In both cases we're accessing '*`. JavaScript doesn't allow asterisk as a name so we need to use the bracket operator.

Clone this wiki locally