Rust enumerated class
Enumeration classes are not as simple as concepts in other programming languages in Rust, but they can still be used very easily:
Example
#[derive(Debug)]
enum Book {
Papery, Electronic
}
fn main() {
let book = Book::Papery;
println!("{:?}", book);
}
Running result:
Papery
Books are divided into paper books and electronic books.
If you are currently developing a library management system, you need to describe the different attributes of the two books (paper books have call numbers, e-books only URL), and you can add tuple attribute descriptions to enumerated class members:
enum Book {
Papery(u32),
Electronic(String),
}
let book = Book::Papery(1001);
let ebook = Book::Electronic(String::from("url://..."));
If you want to name the attribute, you can use the structure syntax:
enum Book {
Papery { index: u32 },
Electronic { url: String },
}
let book = Book::Papery{index: 1001};
Although you can name it this way, note that you cannot access the properties bound to the enumerated class as you would a structural body field. The method of access is in match
in grammar.
Match syntax
The purpose of enumeration is to classify a certain category of things, and the purpose of classification is to describe different situations. Based on this principle, enumerated classes often end up being processed by branch structures (switch in many languages). switch
syntax is classic, but itis not supported in Rust, and many languages abandon it. switch
reason is all because switch
easy to exist due to forgetting to add break
problem of serial operation is eliminated by security checks in languages such as Java and C#.
Rust passed match
statement to implement the branch structure. Let’s first know how to use it. match
handle enumerated classes:
Example
fn main() {
enum Book {
Papery {index: u32},
Electronic {url: String},
}
let book = Book::Papery{index: 1001};
let ebook = Book::Electronic{url: String::from("url...")};
match book {
Book::Papery { index } => {
println!("Papery book {}", index);
},
Book::Electronic { url } => {
println!("E-book {}", url);
}
}
}
Running result:
Papery book 1001
match
blocks can also be treated as function expressions, and it can also have a return value:
Match Enumeration Class Instance{
Category 1=>Return value expression,
Category 2=>Return value expression,
...
}
But all return value expressions must be of the same type!
If you define the additional properties of the enumerated class as tuples, in the match
a name needs to be temporarily specified in the block:
Example
enum Book {
Papery(u32),
Electronic {url: String},
}
let book = Book::Papery(1001);
match book {
Book::Papery(i) => {
println!("{}", i);
},
Book::Electronic { url } => {
println!("{}", url);
}
}
In addition to branch selection for enumerated classes, match
can also branch selection for data of integer, floating-point, character, and string slice reference (& str) types. Among them, although it is legal for floating point type to be selected by branch, it is not recommended because precision problems may lead to branch errors.
When selecting branches for non-enumerated classes, you must pay attention to handling exceptions, even if there is nothing to do in exceptional cases.Use an underscore as an exception \_
indicates:
Example
fn main() {
let t = "abc";
match t {
"abc" => println!("Yes"),
\_ => {},
}
}
Option enumerated class
Option
is an enumerated class in the Rust standard library that is used to fill in Rust’s lack of support null
the white space of the reference.
Many languages support null
is very convenient, but it also creates great problems. null
inventors admit that “a convenient idea has caused a cumulative loss of 1 billion dollars.”
null
often after developers treat everything as no null
give the program a fatal blow: after all, as long as there is such an error, the operation of the program will be completely terminated.
To solve this problem, many languages are not allowed by default null
, But at the language level null
the appearance of (often used before the type? Symbol modification).
Java supports it by default null
, but it can be done through @NotNull
annotation restrictions appear null
, this is a way to deal with it.
Rust does not allow null values at the language level at all. null
the existence of, but helpless null
small number of problems can be solved efficiently, so Rust introduces Option
enumerated classes:
enum Option<T> {
Some(T),
None,
}
If you want to define a class that can be null, you can do this:
let opt = Option::Some("Hello");
If you want to target opt
to perform something, you must first determine whether it is Option::None
:
Example
fn main() {
let opt = Option::Some("Hello");
match opt {
Option::Some(something) => {
println!("{}", something);
},
Option::None => {
println!("opt is nothing");
}
}
}
Running result:
Hello
If your variable is null at first, consider the compiler. How does it know what type of variable is when the value is not null?
So the initial value is empty. Option
type must be clear:
Example
fn main() {
let opt: Option<&str> = Option::None;
match opt {
Option::Some(something) => {
println!("{}", something);
},
Option::None => {
println!("opt is nothing");
}
}
}
Running result:
opt is nothing
This design makes null programming difficult, but it is exactly what is needed to build a stable and efficient system. Due to Option
is introduced by default by the Rust compiler and can be omitted when in use Option::
write directly None
or Some()
.
Option is a special enumeration class that can contain value branch selections:
Example
fn main() {
let t = Some(64);
match t {
Some(64) => println!("Yes"),
\_ => println!("No"),
}
}
if let
Grammar
Example
let i = 0;
match i {
0 => println!("zero"),
\_ => {},
}
Put the running result of the main function:
zero
The purpose of this program is to determine whether I is the number 0, and if so, print it. zero
.
Use it now if let
syntax shortens this code:
let i = 0;
if let 0 = i {
println!("zero");
}
The ``if let``syntax format is as follows:
If let matching value=source variable{
Statement block
}
You can add one later else
block to handle exceptions.
if let
grammar can be thought of as distinguishing only two cases. The match
“grammatical sugar” of a statement (grammatical sugar refersto a convenient substitute with the same principle as a grammar).
It still applies to enumerated classes:
Example
fn main() {
enum Book {
Papery(u32),
Electronic(String)
}
let book = Book::Electronic(String::from("url"));
if let Book::Papery(index) = book {
println!("Papery {}", index);
} else {
println!("Not papery book");
}
}