Last active
October 17, 2018 12:17
-
-
Save Hejsil/89c1516a686509a4afc44446ff38ddb4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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