Commit 183bb8b084

87 <dev@87flowers.com>
2025-01-28 05:23:13
langref: Document destructuring (#21627)
1 parent 41e7604
doc/langref/destructuring_arrays.zig
@@ -0,0 +1,18 @@
+const print = @import("std").debug.print;
+
+fn swizzleRgbaToBgra(rgba: [4]u8) [4]u8 {
+    // readable swizzling by destructuring
+    const r, const g, const b, const a = rgba;
+    return .{ b, g, r, a };
+}
+
+pub fn main() void {
+    const pos = [_]i32{ 1, 2 };
+    const x, const y = pos;
+    print("x = {}, y = {}\n", .{x, y});
+
+    const orange: [4]u8 = .{ 255, 165, 0, 255 };
+    print("{any}\n", .{swizzleRgbaToBgra(orange)});
+}
+
+// exe=succeed
doc/langref/destructuring_block.zig
@@ -0,0 +1,22 @@
+const print = @import("std").debug.print;
+
+pub fn main() void {
+    const digits = [_]i8 { 3, 8, 9, 0, 7, 4, 1 };
+
+    const min, const max = blk: {
+        var min: i8 = 127;
+        var max: i8 = -128;
+
+        for (digits) |digit| {
+            if (digit < min) min = digit;
+            if (digit > max) max = digit;
+        }
+
+        break :blk .{ min, max };
+    };
+
+    print("min = {}", .{ min });
+    print("max = {}", .{ max });
+}
+
+// exe=succeed
doc/langref/destructuring_mixed.zig
@@ -0,0 +1,21 @@
+const print = @import("std").debug.print;
+
+pub fn main() void {
+    var x: u32 = undefined;
+
+    const tuple = .{ 1, 2, 3 };
+
+    x, var y : u32, const z = tuple;
+
+    print("x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    // y is mutable
+    y = 100;
+
+    // You can use _ to throw away unwanted values.
+    _, x, _ = tuple;
+
+    print("x = {}", .{x});
+}
+
+// exe=succeed
doc/langref/destructuring_return_value.zig
@@ -0,0 +1,14 @@
+const print = @import("std").debug.print;
+
+fn divmod(numerator: u32, denominator: u32) struct { u32, u32 } {
+    return .{ numerator / denominator, numerator % denominator };
+}
+
+pub fn main() void {
+    const div, const mod = divmod(10, 3);
+
+    print("10 / 3 = {}\n", .{div});
+    print("10 % 3 = {}\n", .{mod});
+}
+
+// exe=succeed
doc/langref/destructuring_to_existing.zig
@@ -0,0 +1,27 @@
+const print = @import("std").debug.print;
+
+pub fn main() void {
+    var x: u32 = undefined;
+    var y: u32 = undefined;
+    var z: u32 = undefined;
+
+    const tuple = .{ 1, 2, 3 };
+
+    x, y, z = tuple;
+
+    print("tuple: x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    const array = [_]u32{ 4, 5, 6 };
+
+    x, y, z = array;
+
+    print("array: x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    const vector: @Vector(3, u32) = .{ 7, 8, 9 };
+
+    x, y, z = vector;
+
+    print("vector: x = {}, y = {}, z = {}\n", .{x, y, z});
+}
+
+// exe=succeed
doc/langref/destructuring_vectors.zig
@@ -0,0 +1,16 @@
+const print = @import("std").debug.print;
+
+// emulate punpckldq
+pub fn unpack(x: @Vector(4, f32), y: @Vector(4, f32)) @Vector(4, f32) {
+    const a, const c, _, _ = x;
+    const b, const d, _, _ = y;
+    return .{ a, b, c, d };
+}
+
+pub fn main() void {
+    const x: @Vector(4, f32) = .{ 1.0, 2.0, 3.0, 4.0 };
+    const y: @Vector(4, f32) = .{ 5.0, 6.0, 7.0, 8.0 };
+    print("{}", .{unpack(x, y)});
+}
+
+// exe=succeed
doc/langref.html.in
@@ -781,6 +781,30 @@
       implementation feature, not a language semantic, so it is not guaranteed to be observable to code.
       </p>
       {#header_close#}
+
+      {#header_open|Destructuring#}
+      <p>
+        A destructuring assignment can separate elements of indexable aggregate types
+        ({#link|Tuples#}, {#link|Arrays#}, {#link|Vectors#}):
+      </p>
+      {#code|destructuring_to_existing.zig#}
+
+      <p>
+        A destructuring expression may only appear within a block (i.e. not at container scope).
+        The left hand side of the assignment must consist of a comma separated list,
+        each element of which may be either an lvalue (for instance, an existing `var`) or a variable declaration:
+      </p>
+      {#code|destructuring_mixed.zig#}
+
+      <p>
+        A destructure may be prefixed with the {#syntax#}comptime{#endsyntax#} keyword, in which case the entire
+        destructure expression is evaluated at {#link|comptime#}. All {#syntax#}var{#endsyntax#}s declared would
+        be {#syntax#}comptime var{#endsyntax#}s and all expressions (both result locations and the assignee
+        expression) are evaluated at {#link|comptime#}.
+      </p>
+
+      {#see_also|Destructuring Tuples|Destructuring Arrays|Destructuring Vectors#}
+      {#header_close#}
       {#header_close#}
       {#header_close#}
       {#header_open|Zig Test#}
@@ -1882,6 +1906,15 @@ or
 
       {#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Slices#}
       {#header_close#}
+
+      {#header_open|Destructuring Arrays#}
+      <p>
+        Arrays can be destructured:
+      </p>
+      {#code|destructuring_arrays.zig#}
+
+      {#see_also|Destructuring|Destructuring Tuples|Destructuring Vectors#}
+      {#header_close#}
       {#header_close#}
 
       {#header_open|Vectors#}
@@ -1929,6 +1962,14 @@ or
       </p>
       {#see_also|@splat|@shuffle|@select|@reduce#}
 
+      {#header_open|Destructuring Vectors#}
+      <p>
+        Vectors can be destructured:
+      </p>
+      {#code|destructuring_vectors.zig#}
+      {#see_also|Destructuring|Destructuring Tuples|Destructuring Arrays#}
+      {#header_close#}
+
       {#header_close#}
 
       {#header_open|Pointers#}
@@ -2309,6 +2350,23 @@ or
       </p>
       {#code|test_tuples.zig#}
 
+      {#header_open|Destructuring Tuples#}
+      <p>
+        Tuples can be {#link|destructured|Destructuring#}.
+      </p>
+      <p>
+        Tuple destructuring is helpful for returning multiple values from a block:
+      </p>
+      {#code|destructuring_block.zig#}
+
+      <p>
+        Tuple destructuring is helpful for dealing with functions and built-ins that return multiple values
+        as a tuple:
+      </p>
+      {#code|destructuring_return_value.zig#}
+
+      {#see_also|Destructuring|Destructuring Arrays|Destructuring Vectors#}
+      {#header_close#}
       {#header_close#}
       {#see_also|comptime|@fieldParentPtr#}
       {#header_close#}