列舉(Enum)也是各個語言中常見且好用的自訂型別。
和多數語言一樣,enum
可以用來創造一些固定的「選項」,對程式碼可讀性和強健性來說都很好用。比較特別的是,Zig 的 enum
也可以包含方法(method)。
基本
const std = @import("std");
const Color = enum { red, blue, green,};
pub fn main() void { const my_color1 = Color.red; const my_color2: Color = .blue;
if (my_color1 == Color.red) { std.debug.print("Ok\n", .{}); } if (my_color2 == Color.blue) { std.debug.print("Ok", .{}); }}
數值
和其它語言一樣,enum
各項目可以賦予數值,但是要指定儲存的型別,且只能是整數型別。enum
的項目不會直接隱式地轉換成整數值,要用 @intFromEnum()
明確轉型。
const std = @import("std");
const HttpCode = enum(u16) { bad_request = 400, forbidden = 403, not_found = 404, im_a_teapot = 418,};
pub fn main() void { const status = HttpCode.not_found;
if (@intFromEnum(status) == 404) { std.debug.print("Ok", .{}); }}
預設數值
如果不指定數值,或沒有完全指定數值,Zig 會自動遞增。
const std = @import("std");
const Enum1 = enum { value1, value2, value3,};
const Enum2 = enum(u8) { value1 = 100, value2, value3,};
const Enum3 = enum(i8) { value1 = -1, value2, value3,};
const Enum4 = enum(i8) { value1, value2 = 100, value3,};
pub fn main() void { std.debug.print("Enum1: {}, {}, {}\n", .{ @intFromEnum(Enum1.value1), @intFromEnum(Enum1.value2), @intFromEnum(Enum1.value3) });
std.debug.print("Enum2: {}, {}, {}\n", .{ @intFromEnum(Enum2.value1), @intFromEnum(Enum2.value2), @intFromEnum(Enum2.value3) });
std.debug.print("Enum3: {}, {}, {}\n", .{ @intFromEnum(Enum3.value1), @intFromEnum(Enum3.value2), @intFromEnum(Enum3.value3) });
std.debug.print("Enum4: {}, {}, {} ", .{ @intFromEnum(Enum4.value1), @intFromEnum(Enum4.value2), @intFromEnum(Enum4.value3) });}
Enum1: 0, 1, 2Enum2: 100, 101, 102Enum3: -1, 0, 1Enum4: 0, 100, 101
大小
const std = @import("std");
const Enum1 = enum { value1, value2,};
const Enum2 = enum(u16) { value1, value2,};
pub fn main() void { std.debug.print("Int32: {d} byte\n", .{@sizeOf(i32)}); std.debug.print("Enum1: {d} byte\n", .{@sizeOf(Enum1)}); std.debug.print("Enum2: {d} byte\n", .{@sizeOf(Enum2)});}
Int32: 4 byteEnum1: 1 byteEnum2: 2 byte
方法
enum
可以包含方法,這在型別轉換時很有用。
const std = @import("std");
const Color = enum { red, blue, green, others,
pub fn from_string(str: []const u8) Color { if (std.mem.eql(u8, str, "Red")) { return Color.red; } else if (std.mem.eql(u8, str, "Blue")) { return Color.blue; } else if (std.mem.eql(u8, str, "Green")) { return Color.green; } else { return Color.others; } }};
pub fn main() void { const my_color = Color.from_string("Red");
if (my_color == Color.red) { std.debug.print("Ok", .{}); }}
Ok
包含變數或常數
比較特別的是 enum
也可以包含 var
或 const
。
const std = @import("std");
const Enum1 = enum { var my_var: u8 = 0; const my_const: u8 = 100;
value1, value2,};
pub fn main() void { Enum1.my_var += 1;
std.debug.print("Var: {}\n", .{Enum1.my_var}); std.debug.print("Const: {}\n", .{Enum1.my_const});}
Var: 1Const: 100
參考
本文以 Zig 0.13.0
為主。並同時發佈在: