Skip to content

Instantly share code, notes, and snippets.

@lukebayes
Created June 18, 2021 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukebayes/32c51a3df36403742934e8b525d1f56c to your computer and use it in GitHub Desktop.
Save lukebayes/32c51a3df36403742934e8b525d1f56c to your computer and use it in GitHub Desktop.
Example code to help me understand when Zig works with pointers vs copies of structs, especially with Arrays and slices
const std = @import("std");
const expectEqual = std.testing.expectEqual;
const print = std.debug.print;
///////////////////////////////////////////////////////////////////////////////
// Examples for working with Structs and Arrays of Structs
//
// This is intended to help me understand when Zig works with an entity as a
// pointer, and when it makes a copy.
//
// To run this code, just download or place it into a file like, pointers.zig
// and then:
//
// zig test pointers.zig
//
///////////////////////////////////////////////////////////////////////////////
const S = struct {
value: usize = 0,
};
const Copier = struct {
s: S,
};
const Referrer = struct {
s: *S,
};
fn mutate(s: *S) void {
s.value = 20;
}
fn composeCopy(s: S) Copier {
return Copier{
.s = s,
};
}
fn composePtr(s: *S) Referrer {
return Referrer{
.s = s,
};
}
fn mutateCollection(arr: []S) void {
for (arr) |*s| {
s.value += 10;
}
}
test "func with struct" {
const s = S{ .value = 10 };
try expectEqual(s.value, 10);
}
test "func mutation" {
var s = S{ .value = 10 };
mutate(&s); // Remote mutation works with pointer AND var declaration
try expectEqual(s.value, 20);
}
test "func COPIES s" {
var s = S{ .value = 10 };
try expectEqual(s.value, 10);
var c = composeCopy(s);
try expectEqual(c.s.value, 10);
c.s.value = 20;
// Container has a COPY of S.
try expectEqual(s.value, 10);
}
test "func points to s" {
var s = S{ .value = 10 };
try expectEqual(s.value, 10);
var c = composePtr(&s);
try expectEqual(c.s.value, 10);
c.s.value = 20;
// Referrer has a POINTER of S.
try expectEqual(s.value, 20);
}
test "collection of s" {
var arr = [_]S{
.{ .value = 1 },
.{ .value = 2 },
.{ .value = 3 },
};
try expectEqual(arr[0].value, 1);
try expectEqual(arr[1].value, 2);
try expectEqual(arr[2].value, 3);
}
test "&collection of s shares refs" {
var arr = [_]S{
.{ .value = 1 },
.{ .value = 2 },
.{ .value = 3 },
};
print("\n", .{});
// Passing a collection as a slice will mutate entries by reference.
mutateCollection(arr[0..]);
try expectEqual(arr[0].value, 11);
try expectEqual(arr[1].value, 12);
try expectEqual(arr[2].value, 13);
// Passing collection as a pointer will auto-convert to slice and
// mutate entries by reference.
mutateCollection(&arr);
try expectEqual(arr[0].value, 21);
try expectEqual(arr[1].value, 22);
try expectEqual(arr[2].value, 23);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment