Commit 942b250895
Changed files (1)
doc/langref.html.in
@@ -2096,30 +2096,38 @@ const Type = enum {
NotOk,
};
-// Enums are sum types, and can hold more complex data of different types.
-const ComplexType = enum {
- Ok: u8,
- NotOk: void,
-};
-
// Declare a specific instance of the enum variant.
-const c = ComplexType.Ok { 0 };
+const c = Type.Ok;
-// The ordinal value of a simple enum with no data members can be
-// retrieved by a simple cast.
-// The value starts from 0, counting up for each member.
-const Value = enum {
+// If you want access to the ordinal value of an enum, you
+// can specify the tag type.
+const Value = enum(u2) {
Zero,
One,
Two,
};
+
+// Now you can cast between u2 and Value.
+// The ordinal value starts from 0, counting up for each member.
test "enum ordinal value" {
- assert(usize(Value.Zero) == 0);
- assert(usize(Value.One) == 1);
- assert(usize(Value.Two) == 2);
+ assert(u2(Value.Zero) == 0);
+ assert(u2(Value.One) == 1);
+ assert(u2(Value.Two) == 2);
}
-// Enums can have methods, the same as structs.
+// You can override the ordinal value for an enum.
+const Value2 = enum(u32) {
+ Hundred = 100,
+ Thousand = 1000,
+ Million = 1000000,
+};
+test "set enum ordinal value" {
+ assert(u32(Value2.Hundred) == 100);
+ assert(u32(Value2.Thousand) == 1000);
+ assert(u32(Value2.Million) == 1000000);
+}
+
+// Enums can have methods, the same as structs and unions.
// Enum methods are not special, they are only namespaced
// functions that you can call with dot syntax.
const Suit = enum {
@@ -2128,26 +2136,120 @@ const Suit = enum {
Diamonds,
Hearts,
- pub fn ordinal(self: &const Suit) -> u8 {
- u8(*self)
+ pub fn isClubs(self: Suit) -> bool {
+ return self == Suit.Clubs;
}
};
test "enum method" {
const p = Suit.Spades;
- assert(p.ordinal() == 1);
+ assert(!p.isClubs());
}
// An enum variant of different types can be switched upon.
-// The associated data can be retrieved using `|...|` syntax.
-//
-// A void type is not required on a tag-only member.
const Foo = enum {
+ String,
+ Number,
+ None,
+};
+test "enum variant switch" {
+ const p = Foo.Number;
+ const what_is_it = switch (p) {
+ Foo.String => "this is a string",
+ Foo.Number => "this is a number",
+ Foo.None => "this is a none",
+ };
+ assert(mem.eql(u8, what_is_it, "this is a number"));
+}
+
+// @TagType can be used to access the integer tag type of an enum.
+const Small = enum {
+ One,
+ Two,
+ Three,
+ Four,
+};
+test "@TagType" {
+ assert(@TagType(Small) == u2);
+}
+
+// @memberCount tells how many fields an enum has:
+test "@memberCount" {
+ assert(@memberCount(Small) == 4);
+}
+
+// @memberName tells the name of a field in an enum:
+test "@memberName" {
+ assert(mem.eql(u8, @memberName(Small, 1), "Two"));
+}
+
+// @tagName gives a []const u8 representation of an enum value:
+test "@tagName" {
+ assert(mem.eql(u8, @tagName(Small.Three), "Three"));
+}</code></pre>
+ <p>TODO extern enum</p>
+ <p>TODO packed enum</p>
+ <pre><code class="sh">$ zig test enum.zig
+Test 1/8 enum ordinal value...OK
+Test 2/8 set enum ordinal value...OK
+Test 3/8 enum method...OK
+Test 4/8 enum variant switch...OK
+Test 5/8 @TagType...OK
+Test 6/8 @memberCount...OK
+Test 7/8 @memberName...OK
+Test 8/8 @tagName...OK</code></pre>
+ <p>See also:</p>
+ <ul>
+ <li><a href="#builtin-memberName">@memberName</a></li>
+ <li><a href="#builtin-memberCount">@memberCount</a></li>
+ <li><a href="#builtin-tagName">@tagName</a></li>
+ </ul>
+ <h2 id="union">union</h2>
+ <pre><code class="zig">const assert = @import("std").debug.assert;
+const mem = @import("std").mem;
+
+// A union has only 1 active field at a time.
+const Payload = union {
+ Int: i64,
+ Float: f64,
+ Bool: bool,
+};
+test "simple union" {
+ var payload = Payload {.Int = 1234};
+ // payload.Float = 12.34; // ERROR! field not active
+ assert(payload.Int == 1234);
+ // You can activate another field by assigning the entire union.
+ payload = Payload {.Float = 12.34};
+ assert(payload.Float == 12.34);
+}
+
+// Unions can be given an enum tag type:
+const ComplexTypeTag = enum { Ok, NotOk };
+const ComplexType = union(ComplexTypeTag) {
+ Ok: u8,
+ NotOk: void,
+};
+
+// Declare a specific instance of the union variant.
+test "declare union value" {
+ const c = ComplexType { .Ok = 0 };
+ assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
+}
+
+// @TagType can be used to access the enum tag type of a union.
+test "@TagType" {
+ assert(@TagType(ComplexType) == ComplexTypeTag);
+}
+
+// Unions can be made to infer the enum tag type.
+const Foo = union(enum) {
String: []const u8,
Number: u64,
+
+ // void can be omitted when inferring enum tag type.
None,
};
-test "enum variant switch" {
- const p = Foo.Number { 54 };
+test "union variant switch" {
+ const p = Foo { .Number = 54 };
const what_is_it = switch (p) {
// Capture by reference
Foo.String => |*x| {
@@ -2156,6 +2258,7 @@ test "enum variant switch" {
// Capture by value
Foo.Number => |x| {
+ assert(x == 54);
"this is a number"
},
@@ -2163,38 +2266,50 @@ test "enum variant switch" {
"this is a none"
}
};
+ assert(mem.eql(u8, what_is_it, "this is a number"));
}
-// The @memberName and @memberCount builtin functions can be used to
-// the string representation and number of members respectively.
-const BuiltinType = enum {
- A: f32,
- B: u32,
- C,
+// TODO union methods
+
+
+const Small = union {
+ A: i32,
+ B: bool,
+ C: u8,
};
-test "enum builtins" {
- assert(mem.eql(u8, @memberName(BuiltinType.A { 0 }), "A"));
- assert(mem.eql(u8, @memberName(BuiltinType.C), "C"));
- assert(@memberCount(BuiltinType) == 3);
+// @memberCount tells how many fields a union has:
+test "@memberCount" {
+ assert(@memberCount(Small) == 3);
+}
+
+// @memberName tells the name of a field in an enum:
+test "@memberName" {
+ assert(mem.eql(u8, @memberName(Small, 1), "B"));
+}
+
+// @tagName gives a []const u8 representation of an enum value,
+// but only if the union has an enum tag type.
+const Small2 = union(enum) {
+ A: i32,
+ B: bool,
+ C: u8,
+};
+test "@tagName" {
+ assert(mem.eql(u8, @tagName(Small2.C), "C"));
}</code></pre>
- <pre><code class="sh">$ zig test enum.zig
-Test 1/4 enum ordinal value...OK
-Test 2/4 enum method...OK
-Test 3/4 enum variant switch...OK
-Test 4/4 enum builtins...OK</code></pre>
- <p>
- Enums are generated as a struct with a tag field and union field. Zig
+ <pre><code class="sh">$ zig test union.zig
+Test 1/7 simple union...OK
+Test 2/7 declare union value...OK
+Test 3/7 @TagType...OK
+Test 4/7 union variant switch...OK
+Test 5/7 @memberCount...OK
+Test 6/7 @memberName...OK
+Test 7/7 @tagName...OK</code></pre>
+ <p>
+ Unions with an enum tag are generated as a struct with a tag field and union field. Zig
sorts the order of the tag and union field by the largest alignment.
</p>
- <p>See also:</p>
- <ul>
- <li><a href="#builtin-memberName">@memberName</a></li>
- <li><a href="#builtin-memberCount">@memberCount</a></li>
- <li><a href="#builtin-tagName">@tagName</a></li>
- </ul>
- <h2 id="union">union</h2>
- <p>TODO union documentation</p>
<h2 id="switch">switch</h2>
<pre><code class="zig">const assert = @import("std").debug.assert;
const builtin = @import("builtin");