feat: multiple lessons
This commit is contained in:
103
src/macros.rs
Normal file
103
src/macros.rs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
// Group functionality with different types
|
||||||
|
// Define special syntac for specific purpose
|
||||||
|
// Variable number of arguments
|
||||||
|
// Different combination of arguments
|
||||||
|
macro_rules! say_hello {
|
||||||
|
() => {
|
||||||
|
println!("Hello world!");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Types of arguments have designators:
|
||||||
|
// block
|
||||||
|
// expr is used for expressions
|
||||||
|
// ident is used for variable/function names
|
||||||
|
// item
|
||||||
|
// literal is used for literal constants
|
||||||
|
// pat (pattern)
|
||||||
|
// path
|
||||||
|
// stmt (statement)
|
||||||
|
// tt (token tree)
|
||||||
|
// ty (type)
|
||||||
|
// vis (visibility qualifier)
|
||||||
|
macro_rules! generate_function {
|
||||||
|
($func_name:ident) => {
|
||||||
|
fn $func_name() {
|
||||||
|
println!("You called {:?}()", stringify!($func_name));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_function!(foo);
|
||||||
|
|
||||||
|
macro_rules! process_expression {
|
||||||
|
($expression: expr) => {
|
||||||
|
println!("{:?} = {:?}", stringify!($expression), $expression);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload
|
||||||
|
macro_rules! match_block {
|
||||||
|
($left: expr; and $right: expr) => {
|
||||||
|
println!("A: {:?} and {:?}", stringify!($left), stringify!($right))
|
||||||
|
};
|
||||||
|
|
||||||
|
($left: expr; or $right:expr) => {
|
||||||
|
println!(
|
||||||
|
"B: {:?} or {:?} is {:?}",
|
||||||
|
stringify!($left),
|
||||||
|
stringify!($right),
|
||||||
|
$left || $right
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repeat: variable number of args o a type
|
||||||
|
macro_rules! find_max {
|
||||||
|
($x:expr) => ($x);
|
||||||
|
($x:expr, $($y:expr), +) => (std::cmp::max($x, find_max!($($y), +)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// DSLs: Domain Specific Languages
|
||||||
|
// macro_rules allows you to create your own syntax
|
||||||
|
macro_rules! calc {
|
||||||
|
(eval $e:expr) => {
|
||||||
|
println!("{} = {}", stringify!($e), $e);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! calculate {
|
||||||
|
(eval $e: expr) => {
|
||||||
|
{
|
||||||
|
let val: usize = $e; // Force types to be integers
|
||||||
|
println!("{} = {}", stringify!{$e}, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(eval $e: expr, $(eval $y: expr), +) => {{
|
||||||
|
calculate!{eval $e}
|
||||||
|
calculate!{ $(eval $y), + }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn macros_rule() {
|
||||||
|
foo();
|
||||||
|
say_hello!();
|
||||||
|
process_expression!(1 + 5 * 3);
|
||||||
|
|
||||||
|
match_block!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); // Enters first branch
|
||||||
|
match_block!(true; or false); // Enter second branch
|
||||||
|
match_block!(true; and true); // Enters first branch
|
||||||
|
|
||||||
|
println!("Max is {}", find_max!(5, 3 * 8, 4, 9 * 5));
|
||||||
|
|
||||||
|
calc! {
|
||||||
|
eval (1 + 2) * 4
|
||||||
|
}
|
||||||
|
|
||||||
|
calculate! {
|
||||||
|
eval (1 + 2) * 4,
|
||||||
|
eval 1 + 5,
|
||||||
|
eval 7 + 4,
|
||||||
|
eval 3 + 9
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main.rs
18
src/main.rs
@@ -5,18 +5,8 @@
|
|||||||
// : /// Doc comment: generate library docs for the following item
|
// : /// Doc comment: generate library docs for the following item
|
||||||
// : //! Doc comment
|
// : //! Doc comment
|
||||||
|
|
||||||
// mod helloworld;
|
mod macros;
|
||||||
// mod primitives;
|
use macros::macros_rule;
|
||||||
// mod customtypes;
|
|
||||||
//mod variablebindings;
|
|
||||||
// mod types;
|
|
||||||
//mod conversion;
|
|
||||||
// mod controlflow;
|
|
||||||
// mod traits;
|
|
||||||
// mod str_types;
|
|
||||||
// mod functions;
|
|
||||||
// mod exercises;
|
|
||||||
mod concepts;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "./test/basic_test.rs"]
|
#[path = "./test/basic_test.rs"]
|
||||||
@@ -35,5 +25,7 @@ fn main() {
|
|||||||
// exercises::run_easy();
|
// exercises::run_easy();
|
||||||
// my_lib::public_function();
|
// my_lib::public_function();
|
||||||
// functions::functions_module();
|
// functions::functions_module();
|
||||||
concepts::box_basics();
|
// concepts::box_basics();
|
||||||
|
// operators::operators_module();
|
||||||
|
macros_rule();
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/operators.rs
Normal file
24
src/operators.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use std::ops;
|
||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Operators are syntectic sugar for method calls
|
||||||
|
* The + operator calls the add method and so on
|
||||||
|
* */
|
||||||
|
pub fn operators_module() {
|
||||||
|
let a = 3u32.add(3);
|
||||||
|
println!("a is {a}");
|
||||||
|
|
||||||
|
// Operator overloading
|
||||||
|
struct Foo;
|
||||||
|
impl ops::Add<u32> for Foo {
|
||||||
|
type Output = Foo;
|
||||||
|
fn add(self, rhs: u32) -> Self::Output {
|
||||||
|
println!("> add called with {}", rhs);
|
||||||
|
Foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let foo = Foo;
|
||||||
|
let _too = foo + 3; // > add called with 3
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
* 4. Extend the trait with a second function and see what happens
|
* 4. Extend the trait with a second function and see what happens
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
use std::thread::current;
|
||||||
|
|
||||||
pub trait Move {
|
pub trait Move {
|
||||||
fn to(&mut self, x: i32, y: i32);
|
fn to(&mut self, x: i32, y: i32);
|
||||||
}
|
}
|
||||||
@@ -32,4 +34,91 @@ pub fn traits_exercise() {
|
|||||||
me.to(10, 20);
|
me.to(10, 20);
|
||||||
|
|
||||||
println!("My name is {} and i'm at {:?}", me.name, me.position);
|
println!("My name is {} and i'm at {:?}", me.name, me.position);
|
||||||
|
|
||||||
|
// Drop trait: called with an object goes out of scope
|
||||||
|
struct Foo;
|
||||||
|
impl Drop for Foo {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("Foo went out of scope...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut counter = 0u32;
|
||||||
|
loop {
|
||||||
|
if counter > 5 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
counter += 1;
|
||||||
|
let _foo = Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator traits
|
||||||
|
// Example: Fibonacci
|
||||||
|
struct Fibonacci {
|
||||||
|
current: u32,
|
||||||
|
next: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for Fibonacci {
|
||||||
|
type Item = u32;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let current = self.current;
|
||||||
|
self.current = self.next;
|
||||||
|
self.next = self.next + current;
|
||||||
|
Some(current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fib = Fibonacci {
|
||||||
|
current: 0,
|
||||||
|
next: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
for _ in 0..21 {
|
||||||
|
println!("Fib {:?}", fib.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fib = Fibonacci {
|
||||||
|
current: 0,
|
||||||
|
next: 1,
|
||||||
|
};
|
||||||
|
println!("Fib 20 {:?}", fib.nth(20));
|
||||||
|
let fib = Fibonacci {
|
||||||
|
current: 0,
|
||||||
|
next: 1,
|
||||||
|
};
|
||||||
|
println!("Fib skip 20 {:?}", fib.skip(20).next());
|
||||||
|
|
||||||
|
// Disambiguating overlapping traits
|
||||||
|
struct Fee {
|
||||||
|
a: u32,
|
||||||
|
b: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
fn get(&self) -> u32;
|
||||||
|
}
|
||||||
|
trait B {
|
||||||
|
fn get(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl A for Fee {
|
||||||
|
fn get(&self) -> u32 {
|
||||||
|
self.a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl B for Fee {
|
||||||
|
fn get(&self) -> String {
|
||||||
|
self.b.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fee = Fee {
|
||||||
|
a: 1234,
|
||||||
|
b: "asdf".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let a = <Fee as A>::get(&fee);
|
||||||
|
let b = <Fee as B>::get(&fee);
|
||||||
|
println!("The a is {} and the b is {}", a, b);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user