test:zig
This commit is contained in:
105
guide/language/payload-captures.zig
Normal file
105
guide/language/payload-captures.zig
Normal file
@@ -0,0 +1,105 @@
|
||||
const expect = @import("std").testing.expect;
|
||||
|
||||
// Payload captures use the syntax `|value|` and appear in many places, some of which we've seen already.
|
||||
// Wherever they appear, they are used to "capture" the value from something.
|
||||
|
||||
// With if statements and optionals.
|
||||
test "optional-if" {
|
||||
const maybe_num: ?usize = 10;
|
||||
if (maybe_num) |n| {
|
||||
try expect(@TypeOf(n) == usize);
|
||||
try expect(n == 10);
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
// With if statements and error unions. The else with the error capture is required here.
|
||||
test "error union if" {
|
||||
const ent_num: error{UnknownEntity}!u32 = 5;
|
||||
if (ent_num) |entity| {
|
||||
try expect(@TypeOf(entity) == u32);
|
||||
try expect(entity == 5);
|
||||
} else |err| {
|
||||
_ = err catch {};
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
// With while loops and optionals. This may have an else block.
|
||||
test "while optional" {
|
||||
const sequence = [_]?u8{ 0xFF, 0xCC, 0x00, null };
|
||||
|
||||
var i: usize = 0;
|
||||
while (sequence[i]) |num| : (i += 1) {
|
||||
try expect(@TypeOf(num) == u8);
|
||||
}
|
||||
|
||||
try expect(i == 3);
|
||||
try expect(sequence[i] == null);
|
||||
}
|
||||
|
||||
// With while loops and error unions. The else with the error capture is required here.
|
||||
var numbers_left2: u32 = undefined;
|
||||
|
||||
fn eventuallyErrorSequence() !u32 {
|
||||
return if (numbers_left2 == 0) error.ReachedZero else blk: {
|
||||
numbers_left2 -= 1;
|
||||
break :blk numbers_left2;
|
||||
};
|
||||
}
|
||||
|
||||
test "while error union capture" {
|
||||
var sum: u32 = 0;
|
||||
numbers_left2 = 3;
|
||||
while (eventuallyErrorSequence()) |value| {
|
||||
sum += value;
|
||||
} else |err| {
|
||||
try expect(err == error.ReachedZero);
|
||||
}
|
||||
}
|
||||
|
||||
// For loops.
|
||||
test "for capture" {
|
||||
const x = [_]i8{ 1, 5, 120, -5 };
|
||||
for (x) |v| try expect(@TypeOf(v) == i8);
|
||||
}
|
||||
|
||||
// Switch cases on tagged unions.
|
||||
const Info = union(enum) {
|
||||
a: u32,
|
||||
b: []const u8,
|
||||
c,
|
||||
d: u32,
|
||||
};
|
||||
|
||||
test "switch capture" {
|
||||
const b = Info{ .a = 10 };
|
||||
const x = switch (b) {
|
||||
.b => |str| blk: {
|
||||
try expect(@TypeOf(str) == []const u8);
|
||||
break :blk 1;
|
||||
},
|
||||
.c => 2,
|
||||
//if these are of the same type, they
|
||||
//may be inside the same capture group
|
||||
.a, .d => |num| blk: {
|
||||
try expect(@TypeOf(num) == u32);
|
||||
break :blk num * 2;
|
||||
},
|
||||
};
|
||||
try expect(x == 20);
|
||||
}
|
||||
|
||||
// As we saw in the Union and Optional sections above,
|
||||
// values captured with the `|val|` syntax are immutable (similar to function arguments),
|
||||
// but we can use pointer capture to modify the original values.
|
||||
// This captures the values as pointers that are themselves still immutable,
|
||||
// but because the value is now a pointer, we can modify the original value by dereferencing it:
|
||||
const eql = @import("std").mem.eql;
|
||||
|
||||
test "for with pointer capture" {
|
||||
var data = [_]u8{ 1, 2, 3 };
|
||||
for (&data) |*byte| byte.* += 1;
|
||||
try expect(eql(u8, &data, &[_]u8{ 2, 3, 4 }));
|
||||
}
|
||||
Reference in New Issue
Block a user