3 User-defined types
Rust custom types are defined primarily by the following two keys: struct: Define a struct enum: Define an enumerated constant that can be created with the const and static keywords.
3.1 Structure
There are three types of structures ("structs") that can be created using the struct keyword: tuple structure, also named tuple traditional C structure BODY element structure, no field, in order to make common type
A unit struct
struct Nil;
A tuple struct
struct Pair (i32, f64);
A struct with two fields
struct point {
x:f64,
y:f64,
}
//Structs can is reused as fields of Ano ther struct
#[allow (dead_code)]
struct Rectangle {
p1:point,
p2:point,
}
fn Main () {
//Instantiate a ' point ' let
point:point = point {x:0.3, y:0.4};
Access The fields of the point
println! (" Point coordinates: ({}, {}), point.x, point.y);
Destructure the point using a ' let ' binding let point
{x:my_x, y:my_y} = point;
Let _rectangle = rectangle {
//struct instantiation was an expression too p1:point
{x:my_y, y:my_x},
p 2:point,
};
Instantiate a unit struct let
_nil = nil;
Instantiate a tuple struct let
pair = pair (1, 0.1);
Destructure a tuple struct let
Pair (integer, decimal) = Pair;
println! ("pair contains {:?} and {:?} ", Integer, Decimal);
}
Program execution Results:
Point coordinates: (0.3, 0.4)
pair contains 1 and 0.1
3.2 Enumeration
The enum keyword allows you to create a variable that may have many variants. Each VARIANT that is valid for the struct is also valid for enumerations.
An attribute to hide warnings for unused code. #! [Allow (Dead_code)]//Create an ' enum ' to classify someone. Note how both names//and type information together specify the variant://' skinny!= Fat ' and ' Height (I32)!= Weight (i3 2) '.
Each/are different and independent.
Enum Person {//a ' enum ' may either is ' unit-like ', skinny, Fat,//Like tuple structs, Height (I32),
Weight (I32),//or like structures.
Info {name:string, HEIGHT:I32}}//A function which takes a ' person ' enum as A argument and//returns Nothing. fn Inspect (P:person) {//Usage of an ' enum ' must cover all cases (irrefutable)//So a ' match ' are used to branch
Over it. Match p {person::skinny => println! (" Is skinny! "), Person::fat => println!
("is fat!"),//Destructure ' I ' from inside ' enum '. Person::height (i) => println! ("has a height of {}.", i), person::weight (i) => println! ("has a weight of{}. ", i),//Destructure ' Info ' into ' name ' and ' height '. Person::info {name, height} => {println! ("
{} is {} tall! ', name, height);
}, fn main () {Let person = person::height (18);
Let Danny = Person::weight (10);
' to_owned () ' Creates a owned ' string ' from a string slice.
Let Dave = person::info {name: "Dave". to_owned (), height:72};
Let John = Person::fat;
Let Larry = Person::skinny;
Inspect (person);
Inspect (Danny);
Inspect (Dave);
Inspect (John);
Inspect (Larry);
}
Program Run Result:
has a height.
Has a weight.
Dave is tall!
is fat!
Is skinny!
3.2.1 Use
Can be declared with use, so you do not have to specify the scope manually:
An attribute to hide warnings for unused code.
#! [Allow (Dead_code)]
Enum Status {
Rich,
Poor,
}
enum Work {
civilian,
soldier,
}
fn Main () {
/ Explicitly ' use ' each name so they are available without
//manual scoping.
Use Status::{poor, Rich};
Automatically ' use ' Each name inside ' Work '.
Use Work::*;
Equivalent to ' Status::P oor '.
let status = Poor;
Equivalent to ' Work::civilian '.
let work = civilian;
Match status {
//Note the lack of scoping because of the explicit ' use ' above.
Rich => println! ("The rich have lots of money!"),
Poor => println! (" The poor have no money ... "),
match work {
//note again the lack of scoping.
Civilian => println! ("Civilians work!"),
soldier => println! (" Soldiers fight! "),
}
}
Program execution Results:
The poor have no money ...
Civilians work!
3.2.2 C-like
An enum can also be used like a C-prophetic enumeration.
An attribute to hide warnings for unused code.
#! [Allow (Dead_code)]
Enum with implicit discriminator (starts in 0)
enum number {
Zero, one
,
two,
}
//enum with EXP Licit discriminator
enum Color {
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
}
fn Main () {
//' enums ' can be cast as integers.
println! ("Zero is {}", Number::zero as I32);
println! ("One is {}", number::one as I32);
println! ("Roses Are #{:06x}", color::red as I32);
println! ("Violets are #{:06x}", Color::blue as I32);
}
The result of the program running is:
Zero is 0 one is
1
roses are #ff0000
violets are #0000ff
3.2.3 Test Case: Linked list
Enums a common use when creating a linked list:
Use List::*;
Enum List {//cons:tuple struct that wraps a element and a pointer to the next node Cons (u32, box<list>), NIL:A node that signifies the end of the linked list Nil,}//Methods can is attached to an enum Impl list {//Create an empty list fn new ()-> list {//' Nil ' has type ' list ' Nil}//Consume A list, and return to the same list with a new element in its front fn prepend (self, elem:u32)-> list {// ' Cons ' also has Type list Cons (Elem, box::new (self))}//Return the length of the list fn len (&s ELF)-> u32 {//' self ' has to being matched, because the behavior of this method//depends on the Varian T of ' self '//' self ' has type ' &list ', and ' *self ' has type ' List ', matching on a//concrete type ' T ' is preferred over a match on a reference ' &t ' match *self {//Can ' T take ownership of the tail, Because 'Self ' is borrowed; Instead take a reference to the tail Cons (_, ref tail) => 1 + tail.len (),//Base Case:an E Mpty list has zero length Nil => 0}//return representation to the list as a (heap all
ocated) string fn stringify (&self)-> string {match *self {Cons (head, ref tail) => { ' format! ' is similar to ' print! ', but returns a heap//allocated string instead of Prin Ting to the console format! ("{}, {}", Head, Tail.stringify ())}, Nil => {format! ("
Nil ")},}} fn main () {//Create a empty linked list let mut list = List::new ();
Append some elements list = List.prepend (1);
List = List.prepend (2);
List = List.prepend (3); Show the final state of the list println!
("Linked list has length: {}", List.len ()); PrintlN!
("{}", list.stringify ()); }
Program Run Result:
Linked list has length:3
3, 2, 1, Nil
3.3 Constants
Rust has two different types of constants that can function in any definition, including the global. Both methods need to display a declaration: const: An immutable value (usually used) static: A variable "string" that may be mutable within the Staic declaration cycle is a special case. It can be directly assigned to a static variable without modification because its type signature:& ' static STR has already used the ' static lifecycle. All other reference types must use the ' static declaration ' to go up for special annotations.
Globals are declared outside all other scopes.
Static LANGUAGE: & ' static str = ' rust ';
Const THRESHOLD:I32 = ten;
fn Is_big (N:I32)-> bool {
//Access constant in some function
n > THRESHOLD
}
fn main ()
n =;
ACCESS constant in the main thread
println! (" This is {} ", LANGUAGE);
println! ("The threshold is {}", threshold);
println! (' {} is {} ', N, if Is_big (n) {' big '} else {' small '});
error! Cannot modify a ' const '.
THRESHOLD = 5;
Fixme ^ Comment out this line
}
Program Run Result:
This is rust the
threshold is.