On this page
article
Chapter 12: Closures
Basic Closures
-- [capture_list](params): ReturnType { body }
var add = [](x: i32, y: i32): i32 { return x + y; };
debug.print("{}\n", .{add(3, 4)}); -- 7
-- capturing from outer scope
var offset: i32 = 10;
var addOffset = [offset](x: i32): i32 { return x + offset; };
debug.print("{}\n", .{addOffset(5)}); -- 15
Moving Into Closures
Non-Copy values must be moved:
var name = try String::from(alloc, "World");
var greet = [move name](): void {
debug.print("Hello, {}!\n", .{name});
};
-- name is gone from this scope
greet();
Closures as Parameters
fn applyTwice[T](f: fn(*mut T): void, val: *mut T) {
f(val);
f(val);
}
var x: i32 = 0;
applyTwice([&x](_: *mut i32) { x += 1; }, &x);
debug.print("{}\n", .{x}); -- 2
Closures With Collections
fn filter[T](items: []T, pred: fn(*const T): bool, alloc: Allocator): ![]T {
var result = List[T]::new();
errdefer result.deinit(alloc);
for item in items {
if pred(item) {
try result.push(alloc, item.*);
}
}
return result.intoSlice();
}
var numbers = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 };
var evens = try filter(&numbers, [](n: *const i32): bool {
return n.* % 2 = 0;
}, alloc);
defer alloc.free(evens);
-- evens: { 2, 4, 6, 8 }