mirror of
https://bitbucket.org/Mattrixwv/rusttutorials.git
synced 2025-12-06 18:43:57 -05:00
Added chapter 3
This commit is contained in:
92
3.CustomTypes/1Structures.rs
Normal file
92
3.CustomTypes/1Structures.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
#[derive(Debug)]
|
||||
struct Person<'a>{
|
||||
//The 'a defines a lifetime
|
||||
name: &'a str,
|
||||
age: u8,
|
||||
}
|
||||
|
||||
//A unit struct
|
||||
struct Unit;
|
||||
|
||||
//A tuple struct
|
||||
struct Pair(i32, f32);
|
||||
|
||||
//A struct with two fields
|
||||
struct Point{
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
//Structs can be reused as fields of another struct
|
||||
#[allow(dead_code)]
|
||||
struct Rectangle{
|
||||
//A rectangle can be specified by where the top left and bottom right corners are in space.
|
||||
top_left: Point,
|
||||
bottom_right: Point,
|
||||
}
|
||||
//Get the area of a rectangle
|
||||
fn rect_area(rect: Rectangle) -> f32{
|
||||
let width = rect.top_left.x + rect.bottom_right.x;
|
||||
let height = rect.bottom_right.y + rect.top_left.y;
|
||||
return width * height;
|
||||
}
|
||||
//Create a square
|
||||
fn square(pnt: Point, side: f32) -> Rectangle{
|
||||
#[allow(non_snake_case)]
|
||||
let topLeft = Point{ x: pnt.x, y: pnt.y + side };
|
||||
#[allow(non_snake_case)]
|
||||
let bottomRight = Point{ x: pnt.x + side, y: pnt.y };
|
||||
#[allow(non_snake_case)]
|
||||
let rect = Rectangle{ top_left: topLeft, bottom_right : bottomRight };
|
||||
return rect;
|
||||
}
|
||||
|
||||
fn main(){
|
||||
//Create struct with field init shorthand
|
||||
let name = "Peter";
|
||||
let age = 27;
|
||||
let peter = Person { name, age };
|
||||
|
||||
//Print debug struct
|
||||
println!("{:?}", peter);
|
||||
|
||||
//Instantiate a `Point`
|
||||
let point: Point = Point { x: 10.3, y: 0.4 };
|
||||
|
||||
//Access the fields of the point
|
||||
println!("point coordinates: ({}, {})", point.x, point.y);
|
||||
|
||||
//Make a new point by using struct update syntax to use the fields of our other one
|
||||
let bottom_right = Point { x: 5.2, ..point };
|
||||
|
||||
//`bottom_right.y` will be the same as `point.y` because we used that field from `point`
|
||||
println!("second point: ({}, {})", bottom_right.x, bottom_right.y);
|
||||
|
||||
//Destructure the point using a `let` binding
|
||||
let Point { x: top_edge, y: left_edge } = point;
|
||||
|
||||
let _rectangle = Rectangle{
|
||||
//struct instantiation is an expression too
|
||||
top_left: Point { x: left_edge, y: top_edge },
|
||||
bottom_right: bottom_right,
|
||||
};
|
||||
|
||||
//Instantiate a unit struct
|
||||
let _unit = Unit;
|
||||
|
||||
//Instantiate a tuple struct
|
||||
let pair = Pair(1, 0.1);
|
||||
|
||||
//Access the fields of a tuple struct
|
||||
println!("pair contains {:?} and {:?}", pair.0, pair.1);
|
||||
|
||||
//Destructure a tuple struct
|
||||
let Pair(integer, decimal) = pair;
|
||||
|
||||
println!("pair contains {:?} and {:?}", integer, decimal);
|
||||
|
||||
println!("rectangle points: {}, {}; {}, {}", _rectangle.top_left.x, _rectangle.top_left.y, _rectangle.bottom_right.x, _rectangle.bottom_right.y);
|
||||
println!("rectangle area = {}", rect_area(_rectangle));
|
||||
let rect = square(point, 1.0);
|
||||
println!("square = {}, {}; {}, {}", rect.top_left.x, rect.top_left.y, rect.bottom_right.x, rect.bottom_right.y);
|
||||
}
|
||||
36
3.CustomTypes/2.Enums/1Use.rs
Normal file
36
3.CustomTypes/2.Enums/1Use.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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 crate::Status::{Poor, Rich};
|
||||
//Automatically `use` each name inside `Work`.
|
||||
use crate::Work::*;
|
||||
|
||||
//Equivalent to `Status::Poor`.
|
||||
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!"),
|
||||
}
|
||||
}
|
||||
25
3.CustomTypes/2.Enums/2CLike.rs
Normal file
25
3.CustomTypes/2.Enums/2CLike.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
//An attribute to hide warnings for unused code.
|
||||
#![allow(dead_code)]
|
||||
|
||||
//enum with implicit discriminator (starts at 0)
|
||||
enum Number{
|
||||
Zero,
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
//enum with explicit 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);
|
||||
}
|
||||
62
3.CustomTypes/2.Enums/3TestCase-LinkedList.rs
Normal file
62
3.CustomTypes/2.Enums/3TestCase-LinkedList.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use crate::List::*;
|
||||
|
||||
enum List{
|
||||
//Cons: Tuple struct that wraps an 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 be attached to an enum
|
||||
impl List{
|
||||
//Create an empty list
|
||||
fn new() -> List {
|
||||
//`Nil` has type `List`
|
||||
Nil
|
||||
}
|
||||
|
||||
//Consume a list, and return the same list with a new element at 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(&self) -> u32 {
|
||||
//`self` has to be matched, because the behavior of this method depends on the variant 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 empty list has zero length
|
||||
Nil => 0
|
||||
}
|
||||
}
|
||||
|
||||
//Return representation of the list as a (heap allocated) string
|
||||
fn stringify(&self) -> String{
|
||||
match *self{
|
||||
Cons(head, ref tail) => {
|
||||
// `format!` is similar to `print!`, but returns a heap
|
||||
// allocated string instead of printing to the console
|
||||
format!("{}, {}", head, tail.stringify())
|
||||
},
|
||||
Nil => {
|
||||
format!("Nil")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main(){
|
||||
//Create an empty linked list
|
||||
let mut list = List::new();
|
||||
|
||||
//Prepend 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());
|
||||
}
|
||||
62
3.CustomTypes/2Enums.rs
Normal file
62
3.CustomTypes/2Enums.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
//Create an `enum` to classify a web event. Note how both
|
||||
//names and type information together specify the variant:
|
||||
//`PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`.
|
||||
//Each is different and independent.
|
||||
enum WebEvent{
|
||||
//An `enum` may either be `unit-like`,
|
||||
PageLoad,
|
||||
PageUnload,
|
||||
//like tuple structs,
|
||||
KeyPress(char),
|
||||
Paste(String),
|
||||
//or c-like structures.
|
||||
Click { x: i64, y: i64 },
|
||||
}
|
||||
|
||||
//A function which takes a `WebEvent` enum as an argument and returns nothing.
|
||||
fn inspect(event: WebEvent){
|
||||
match event{
|
||||
WebEvent::PageLoad => println!("page loaded"),
|
||||
WebEvent::PageUnload => println!("page unloaded"),
|
||||
// Destructure `c` from inside the `enum`.
|
||||
WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
|
||||
WebEvent::Paste(s) => println!("pasted \"{}\".", s),
|
||||
// Destructure `Click` into `x` and `y`.
|
||||
WebEvent::Click { x, y } =>{
|
||||
println!("clicked at x={}, y={}.", x, y);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
enum VeryVerboseEnumOfThingsToDoWithNumbers{
|
||||
Add,
|
||||
Subtract,
|
||||
}
|
||||
// Creates a type alias
|
||||
type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;
|
||||
impl VeryVerboseEnumOfThingsToDoWithNumbers{
|
||||
fn run(&self, x: i32, y: i32) -> i32{
|
||||
match self{
|
||||
Self::Add => x + y,
|
||||
Self::Subtract => x - y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let pressed = WebEvent::KeyPress('x');
|
||||
//`to_owned()` creates an owned `String` from a string slice.
|
||||
let pasted = WebEvent::Paste("my text".to_owned());
|
||||
let click = WebEvent::Click { x: 20, y: 80 };
|
||||
let load = WebEvent::PageLoad;
|
||||
let unload = WebEvent::PageUnload;
|
||||
|
||||
inspect(pressed);
|
||||
inspect(pasted);
|
||||
inspect(click);
|
||||
inspect(load);
|
||||
inspect(unload);
|
||||
|
||||
// We can refer to each variant via its alias, not its long and inconvenient name.
|
||||
let x = Operations::Add;
|
||||
}
|
||||
21
3.CustomTypes/3Constants.rs
Normal file
21
3.CustomTypes/3Constants.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
//Globals are declared outside all other scopes.
|
||||
static LANGUAGE: &str = "Rust";
|
||||
const THRESHOLD: i32 = 10;
|
||||
|
||||
fn is_big(n: i32) -> bool{
|
||||
//Access constant in some function
|
||||
n > THRESHOLD
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let n = 16;
|
||||
|
||||
//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
|
||||
}
|
||||
Reference in New Issue
Block a user