My cheatsheet for Ziglang
Tags: zig
Published: 2022-09-18 12:54:33

## How to confirm OS type

```zig
const std = @import("std");
const builtin = @import("builtin");

test "confirm OS type" {
    const is_windows = builtin.os.tag == .windows;
    std.debug.print("is windows = {}\n", .{is_windows});

    const is_mac = builtin.os.tag == .macos;
    std.debug.print("is mac = {}\n", .{is_mac});

    const is_linux = builtin.os.tag == .linux;
    std.debug.print("is linux = {}\n", .{is_linux});

    std.debug.print("this os is {}\n", .{builtin.os.tag});
}
```

## usingnamespace

- namespace is struct, union, enum or opaque in Ziglang. (see [document](https://ziglang.org/documentation/master/#usingnamespace)).
- You can use pub functions and declarations in the namespace. You can't use ones without `pub`.
- You can use it like mixin.

```zig
const std = @import("std");
const testing = std.testing;

test "usingnamespace" {

  const S = struct {
    usingnamespace @import("std");

    /// this property does not become a member in caller struct due to lack of `pub`
    const NOT_IN_NAMESPACE_NUM = 11;

    /// this property becomes a member with usingnamespace.
    pub const NUM =12;

    /// this property does not become a member in caller struct due to lack of `pub`
    fn notInNamespaceFunc() bool {
      return false;
    }

    /// this property becomes a member with usingnamespace.
    pub fn inNamespaceFunc() bool {
      return true;
    }
  };

  // caller struct for S.
  const T = struct {
    usingnamespace S;
  };

  // usingnamespace T;  // this statement can not be compiled.

  // you can use all members from S scope.
  try S.testing.expect(true);
  try S.testing.expectEqual(S.NOT_IN_NAMESPACE_NUM, 11);
  try S.testing.expectEqual(S.NUM, 12);
  try testing.expect(!S.notInNamespaceFunc());
  try testing.expect(S.inNamespaceFunc());

  // you can use only members with pub in S from T scope.
  // try testing.expectEqual(T.NOT_IN_NAMESPACE_NUM, 11);  // this statement can not be compiled.
  try testing.expectEqual(T.NUM, 12);
  // try testing.expect(!T.notInNamespaceFunc());  // this statement can not be compiled.
  try testing.expect(T.inNamespaceFunc());
}
```

## How to handle command-line args

- How to use the following code:
  - with building:
      - e.g. for building: `$ zig build-exe main.zig -O Debug`
      - e.g. for executing: `$ ./main.exe arg1 arg2`
  - with `run` command:
      - e.g. `$ zig run main.zig -- arg1 arg2`

```zig
const std = @import("std");
const process = std.process;


const Args = struct {
  const Self = @This();

  allocator: std.mem.Allocator,
  items: [][:0]u8,

  pub fn init(allocator: std.mem.Allocator) !Args {
    return Args{
      .allocator = allocator,
      .items = try process.argsAlloc(allocator),
    };
  }

  pub fn deinit(self: Self) void {
    defer process.argsFree(self.allocator, self.items);
  }

  pub fn print(self: Self) void {
    for (self.items) |item, i| {
      std.debug.print("arg[{d}]={s}\n", .{i, item});
    }
  }
};


pub fn main() !void {
  var gpa = std.heap.GeneralPurposeAllocator(.{}){};
  const allocator = gpa.allocator();
  defer std.debug.assert(!gpa.deinit());

  const args = try Args.init(allocator);
  defer args.deinit();
  args.print();

  // how to access individual arguments
  for (args.items) |item, i| {
    std.debug.print("args[{d}] from props={s}\n", .{i, item});
  }
}
```