This is the 29th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

Enumerations are also called enums. Enumerations allow you to define a type by enumerating its possible members.

Enumeration is a feature found in many languages, but it varies from language to language. Rust’s enumeration is most similar to algebraic data types in functional programming languages such as F#, OCaml, and Haskell.

Define the enumeration

So why use enumerations? We know that enumerations can be used to list all possible values, such as when we are dealing with IP addresses, the two main IP standards that are widely used today: IPv4 (Version four) and IPv6 (Version six). Any IP address can be either IPv4 or IPv6, and not both. This property of IP addresses makes enumeration data structures ideal for this scenario, because the enumeration value can only be one of its members. IPv4 and IPv6 are still fundamentally IP addresses, so code should treat them as the same type when dealing with scenarios that apply to any type of IP address.

From this we will be able to define an IPAddr enumeration in our code to express this concept and list the possible IP address types. The IP address type V4 v6 will be called a member of the enumeration and IPAddr will then become a custom data type that can be used in our code:

enum IPAddr {
    v4,  // Used by different members of enumeration, separated
    v6,
}
Copy the code

Enumerated values

With IPAddr in hand, you can create instances of different members in code like this:

enum IPAddr {
    v4,  // Used by different members of enumeration, separated
    v6,
}

fn main() {
    let four = IPAddr::v4;
    let six = IPAddr::v6;
}
Copy the code

There are many benefits to using enumerations, such as there is currently no way to store actual IP address data; We just know what type it is. Based on the structure mentioned in the previous article, this requirement can be handled as follows:

enum IpAddrKind {
    V4,
    V6,
}

struct IpAddr {
    kind: IpAddrKind,
    address: String,}let home = IpAddr {
    kind: IpAddrKind::V4,
    address: String::from("127.0.0.1"),};let loopback = IpAddr {
    kind: IpAddrKind::V6,
    address: String::from(: : "1"),};Copy the code

Here we define a structure IpAddr with two fields: The IpAddrKind (previously defined enumeration) kind field and the String Address field use a structure to wrap kind and Address together, and now the enumeration member is associated with the value.

A more concise way to express the same concept is to just use enumerations and put the data directly into each enumerator rather than making the enumeration part of the structure. The new definition of the IpAddr enumeration shows that both V4 and V6 members are associated with a String value, as shown in the following code:

enum IpAddr {
    V4(String),
    V6(String),}let home = IpAddr::V4(String::from("127.0.0.1"));

let loopback = IpAddr::V6(String::from(: : "1"));
Copy the code

Append data directly to each member of the enumeration, eliminating the need for an additional structure.

Using enumerations instead of constructs has another advantage: each member can handle different types and amounts of data. The IPv4 version of an IP address always contains four numeric parts with values between 0 and 255. If you want to store the V4 address as four U8 values while the V6 address still appears as a String, you can’t use a structure. Enumerations can easily handle this situation:

enum IpAddr {
    V4(u8.u8.u8.u8),
    V6(String),}let home = IpAddr::V4(127.0.0.1);

let loopback = IpAddr::V6(String::from(: : "1"));
Copy the code

conclusion

The article was first published in the wechat public account Program Yuan Xiaozhuang, at the same time in nuggets.

The code word is not easy, reprint please explain the source, pass by the little friends of the lovely little finger point like and then go (╹▽╹)