Payload Captures
Las capturas de carga utilizan la sintaxis |valor| y aparecen en muchos lugares, algunos de los cuales ya hemos visto. Dondequiera que aparezcan, se utilizan para “capturar” el valor de algo.
Con las declaraciones if y los optionals.
test "optional-if" {
const maybe_num: ?usize = 10;
if (maybe_num) |n| {
try expect(@TypeOf(n) == usize);
try expect(n == 10);
} else {
unreachable;
}
}
Con las declaraciones if y las uniones de errores. El else con la captura de error es requerido aquí.
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;
}
}
Con los bucles while y los optionals. Esto puede tener un bloque else.
test "while optional" {
var i: ?u32 = 10;
while (i) |num| : (i.? -= 1) {
try expect(@TypeOf(num) == u32);
if (num == 1) {
i = null;
break;
}
}
try expect(i == null);
}
Con los bucles while y las uniones de errores. El else con la captura de error es requerido aquí.
const expect = @import("std").testing.expect;
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);
}
}
Para loops.
test "for capture" {
const x = [_]i8{ 1, 5, 120, -5 };
for (x) |v| try expect(@TypeOf(v) == i8);
}
Casos de switch en uniones etiquetadas.
const expect = @import("std").testing.expect;
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,
// Si estos son del mismo tipo,
//pueden estar dentro del mismo grupo de captura.
.a, .d => |num| blk: {
try expect(@TypeOf(num) == u32);
break :blk num * 2;
},
};
try expect(x == 20);
}
Como vimos en las secciones de Union y Optional anteriormente, los valores capturados con la sintaxis |val| son inmutables (similar a los argumentos de función), pero podemos usar la captura de puntero para modificar los valores originales. Esto captura los valores como punteros que aún son inmutables, pero debido a que el valor es ahora un puntero, podemos modificar el valor original desreferenciándolo: