Declarations
Enums
Declare a closed set of named integer-backed values, convert to and from their codes, and match on them exhaustively.
since 0.1.0-alpha.1linuxwindowswasm
Description
An enum declares a closed set of named members. Each member carries an int value, its code.
An enum is a value type: it is copied, has no identity, and cannot be inherited from.
enum Method { GET, HEAD, POST } // codes 0, 1, 2
enum Status : int { OK = 200, NotFound = 404, Teapot = 418 } // explicit codes
enum Gap : int { A, B = 10, C } // A = 0, B = 10, C = 11
Members are reached with :: on the enum's name. code() returns the member's integer, and
toString() returns its name. Method::fromCode(n) turns a code back into a member, and yields
None when no member has that code, so its type is Method?. A variable declared without an
initializer holds the first-declared member.
Members, codes, names and fromCode
enum Method { GET, HEAD, POST }
enum Status : int { OK = 200, NotFound = 404, Teapot = 418 }
enum Gap : int { A, B = 10, C }
Method m = Method::GET;
console.writeln(m.code());
console.writeln(m.toString());
console.writeln(Method::POST.code());
console.writeln(Gap::C.code());
Method d;
console.writeln(d.toString());
Method? found = Method::fromCode(1);
if (found != None) {
console.writeln(found.toString());
}
console.writeln(Status::fromCode(999) == None);
console.writeln(Method::GET == Method::GET);
console.writeln(Method::GET != Method::POST);
console.writeln("${Status::NotFound.toString()} is ${Status::NotFound.code()}");
0
GET
2
11
GET
HEAD
true
true
true
NotFound is 404
Rules
- Without
: intthe codes count up from0. With explicit codes, a member that has none takes the previous member's code plus one (Gap::Cis11). intis the only carrier type. Two members with the same code are a compile error.==and!=compare enum values by code.- An enum value used as a
Mapkey or aSetelement compares by value. Enum::fromCode(int)returnsEnum?,Noneif no member has that code.matchover an enum is exhaustive: when every member has an arm, noelseis needed; leaving a member out is a compile error that names the missing members. Anelsearm is still allowed and covers the members not listed.- A bare declaration
Method d;is the first-declared member.
Examples
Matching on an enum:
Exhaustive match and else
enum Method { GET, HEAD, POST }
enum Status : int { OK = 200, NotFound = 404, Teapot = 418 }
string name(Method x) {
return match (x) {
Method::GET => "read";
Method::HEAD => "peek";
Method::POST => "write";
};
}
string kind(Status s) {
return match (s) {
Status::OK => "ok";
else => "other";
};
}
console.writeln(name(Method::HEAD));
console.writeln(kind(Status::Teapot));
Map<Method, string> verbs;
verbs = verbs.with(Method::POST, "create");
console.writeln(verbs.at(Method::POST));
peek
other
create
An incomplete match and duplicate codes are compile errors:
Errors
enum Method { GET, HEAD, POST }
string name(Method x) {
return match (x) {
Method::GET => "read";
Method::HEAD => "peek";
}; // error: non-exhaustive match on enum 'Method': missing Method::POST
}
enum Bad : int { A = 1, B = 1 } // error: duplicate enum carrier value 1
Notes
Not implemented: carriers other than int (an enum S : string is a compile error), and ordering
comparisons such as < between enum members. Compare the results of code() instead.
See also
- Value structs — Declare value types that are copied on every assignment, pass and return, with derived equality and explicit mutating methods.