mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 23:22:44 +00:00
bfcf18c5a7
Some checks failed
ci / x86_64-linux-debug (push) Has been cancelled
ci / x86_64-linux-release (push) Has been cancelled
ci / aarch64-linux-debug (push) Has been cancelled
ci / aarch64-linux-release (push) Has been cancelled
ci / x86_64-macos-release (push) Has been cancelled
ci / aarch64-macos-debug (push) Has been cancelled
ci / aarch64-macos-release (push) Has been cancelled
ci / x86_64-windows-debug (push) Has been cancelled
ci / x86_64-windows-release (push) Has been cancelled
ci / aarch64-windows (push) Has been cancelled
127 lines
3.0 KiB
Zig
127 lines
3.0 KiB
Zig
// Declare a struct.
|
|
// Zig gives no guarantees about the order of fields and the size of
|
|
// the struct but the fields are guaranteed to be ABI-aligned.
|
|
const Point = struct {
|
|
x: f32,
|
|
y: f32,
|
|
};
|
|
|
|
// Declare an instance of a struct.
|
|
const p: Point = .{
|
|
.x = 0.12,
|
|
.y = 0.34,
|
|
};
|
|
|
|
// Functions in the struct's namespace can be called with dot syntax.
|
|
const Vec3 = struct {
|
|
x: f32,
|
|
y: f32,
|
|
z: f32,
|
|
|
|
pub fn init(x: f32, y: f32, z: f32) Vec3 {
|
|
return Vec3{
|
|
.x = x,
|
|
.y = y,
|
|
.z = z,
|
|
};
|
|
}
|
|
|
|
pub fn dot(self: Vec3, other: Vec3) f32 {
|
|
return self.x * other.x + self.y * other.y + self.z * other.z;
|
|
}
|
|
};
|
|
|
|
test "dot product" {
|
|
const v1 = Vec3.init(1.0, 0.0, 0.0);
|
|
const v2 = Vec3.init(0.0, 1.0, 0.0);
|
|
try expect(v1.dot(v2) == 0.0);
|
|
|
|
// Other than being available to call with dot syntax, struct methods are
|
|
// not special. You can reference them as any other declaration inside
|
|
// the struct:
|
|
try expect(Vec3.dot(v1, v2) == 0.0);
|
|
}
|
|
|
|
// Structs can have declarations.
|
|
// Structs can have 0 fields.
|
|
const Empty = struct {
|
|
pub const PI = 3.14;
|
|
};
|
|
test "struct namespaced variable" {
|
|
try expect(Empty.PI == 3.14);
|
|
try expect(@sizeOf(Empty) == 0);
|
|
|
|
// Empty structs can be instantiated the same as usual.
|
|
const does_nothing: Empty = .{};
|
|
|
|
_ = does_nothing;
|
|
}
|
|
|
|
// Struct field order is determined by the compiler, however, a base pointer
|
|
// can be computed from a field pointer:
|
|
fn setYBasedOnX(x: *f32, y: f32) void {
|
|
const point: *Point = @fieldParentPtr("x", x);
|
|
point.y = y;
|
|
}
|
|
test "field parent pointer" {
|
|
var point = Point{
|
|
.x = 0.1234,
|
|
.y = 0.5678,
|
|
};
|
|
setYBasedOnX(&point.x, 0.9);
|
|
try expect(point.y == 0.9);
|
|
}
|
|
|
|
// Structs can be returned from functions.
|
|
fn LinkedList(comptime T: type) type {
|
|
return struct {
|
|
pub const Node = struct {
|
|
prev: ?*Node,
|
|
next: ?*Node,
|
|
data: T,
|
|
};
|
|
|
|
first: ?*Node,
|
|
last: ?*Node,
|
|
len: usize,
|
|
};
|
|
}
|
|
|
|
test "linked list" {
|
|
// Functions called at compile-time are memoized.
|
|
try expect(LinkedList(i32) == LinkedList(i32));
|
|
|
|
const list = LinkedList(i32){
|
|
.first = null,
|
|
.last = null,
|
|
.len = 0,
|
|
};
|
|
try expect(list.len == 0);
|
|
|
|
// Since types are first class values you can instantiate the type
|
|
// by assigning it to a variable:
|
|
const ListOfInts = LinkedList(i32);
|
|
try expect(ListOfInts == LinkedList(i32));
|
|
|
|
var node = ListOfInts.Node{
|
|
.prev = null,
|
|
.next = null,
|
|
.data = 1234,
|
|
};
|
|
const list2 = LinkedList(i32){
|
|
.first = &node,
|
|
.last = &node,
|
|
.len = 1,
|
|
};
|
|
|
|
// When using a pointer to a struct, fields can be accessed directly,
|
|
// without explicitly dereferencing the pointer.
|
|
// So you can do
|
|
try expect(list2.first.?.data == 1234);
|
|
// instead of try expect(list2.first.?.*.data == 1234);
|
|
}
|
|
|
|
const expect = @import("std").testing.expect;
|
|
|
|
// test
|