Skip to content

Instantly share code, notes, and snippets.

@Hejsil
Last active October 17, 2018 12:17
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 Hejsil/89c1516a686509a4afc44446ff38ddb4 to your computer and use it in GitHub Desktop.
Save Hejsil/89c1516a686509a4afc44446ff38ddb4 to your computer and use it in GitHub Desktop.
const assert = @import("std").debug.assert;
test "Multible return values" {
const S = struct { a: u8, b: []const u8 };
// Structs and arrays can be desconstructed into their fields/items.
const a, var b = S.{ .a = 0, .b = "" };
const a, var b = [2]u16{1, 2};
// This allows for multible return types from both functions and labled blocks:
const min, const max = blk: {
var arr = []u8{2,3,5,2};
var min = arr[0];
var max = arr[0];
for (arr[1..]) |i| {
if (i < min)
min = i;
if (max < i)
max = i;
}
break :blk []u8.{min, max};
};
assert(min == 2 and max == 5);
}
test "Inferred initializers" {
// Inferred initializers are initializers whos types are inferred from the context
// in which they are used. They allow for shorthand initialization where it does
// not improve readablilty to append the initializer with a type.
// Inferred initializers come i 3 syntactic flavors.
// structs and unions will use "inferred struct initializers"
const s: struct.{a: i32, b: []const u8} = .{ .a = 0, .b = "" };
const u: union.{A: i32, B: []const u8} = .{ .A = 0 };
// arrays will use "inferred array initializers"
const a: [2]u8 = .{0, 1};
// enums will use "inferred enum initializers"
const e: enum.{A, B} = .A;
// They will have their own internal temporary type, which implicitly cast to
// other types using the following rules:
// * "inferred struct initializers" will implicitly cast to:
// * Structs, If:
// * The initializer has the same number of fields as the struct.
// * All initializer field names are also in the struct.
// * All initializer fields implicitly casts to the struct field of the
// same name.
// * Unions, If:
// * The initializer has 1 field.
// * The initializers fields name is contained in the union.
// * The initializers field implicitly casts to the tag of that name.
// * They will also cast to a normal struct, if none of the above is true.
// * This is useful for passing inferred struct initializers to functions
// taking "var".
// * "inferred array initializers" will implicitly cast to:
// * Arrays, If:
// * The initializer has the same number of items as the array.
// * All initializers items implicitly cast to the arrays item.
// * They will also cast to a normal array, if none of the above is true.
// * This is useful for passing inferred arrays initializers to functions
// taking "var".
// * "inferred enum initializers" will implicitly cast to:
// * Enum, If:
// * The initializers name is contained in the enum.
// * Union, If:
// * The initializers name is contained in the union.
// * The initializers name in the union is "void".
// * They will also cast to a normal enum, if none of the above is true.
// * This is useful for passing inferred enums initializers to functions
// taking "var".
// Implicitly casts to enum{E}
_ = @typeOf(.E);
_ = funcTakingVar(.E);
var a = .E;
// Implicitly casts to struct.{a: u8, b: u8}
_ = @typeOf(.{ .a = u8(2), .b = u8(4) });
_ = funcTakingVar(.{ .a = u8(2), .b = u8(4) });
var a = .{ .a = u8(2), .b = u8(4) };
// Implicitly casts to [2]u16
_ = @typeOf(.{ u8(2), u16(4) });
_ = funcTakingVar(.{ u8(2), u16(4) });
var a = .{ u8(2), u16(4) };
}
// *** Varargs ***
// We can remove varargs, and have std.debug.warn be used like this:
fn warn(comptime fmt: []const u8, args: var) void { ... };
test "warn" {
// This proposal does not solve passing comptime_int to varargs functions
// VVVVV
warn("{} {}", .{ .a = u8(1), .b = "yo" });
// We can also use the names to have order independent fmt
warn("{b} {a}", .{ .a = u8(1), .b = "yo" });
// Format params will be passed after the ':'
// V V
warn("{:x} {a:x}", .{ .a = u8(1) });
}
// This also allows us to have "typed varargs" functionality:
fn concat(args: [][]const u8) []const u8 { ... };
test "concat" {
const res = concat(.{"Hello", " ", "World!\n"});
}
// *** Named arguments ***
// related: https://github.com/ziglang/zig/issues/479
const Flags = struct {
turn_on_nuke: bool,
go_full_screen: bool,
take_over_the_univers: bool,
};
fn something(flags: Flags) void { ... }
test "named args" {
// With https://github.com/ziglang/zig/issues/485, we even get default argument
// (https://github.com/ziglang/zig/issues/484) values.
something(.{
.take_over_the_univers = true,
.turn_on_nuke = true,
.go_full_screen = false,
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment