/* * Author: 邹航标 (No. 43) * * Useful links: * * https://github.com/AmadeusGB/SubstrateClass/blob/master/lesson5/area/src/main.rs * https://shimo.im/docs/rTJPC8PTpD3xJGVY/read * https://wj.qq.com/s2/7525430/1f79/ * https://play.rust-lang.org/ */ // solution 1 #[derive(Debug)] enum TrafficLight { Red, Green, Yellow, } trait Light { fn duration(&self) -> i32; } impl Light for TrafficLight { fn duration(&self) -> i32 { return match self { TrafficLight::Red => 30, TrafficLight::Green => 5, TrafficLight::Yellow => 45, }; } } // https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax // fn display_light(l: T){ // fn display_light(l: impl Light + std::fmt::Debug){ fn _display_light(light: T) where T: Light + std::fmt::Debug { println!("{:?} light lasts for {}s", light, light.duration()) } macro_rules! display_light { ($( $light:expr),* $(,)?) => {{ $( println!("{:?} light lasts for {}s", $light, $light.duration()); )* }}; } fn solution1() { display_light!( TrafficLight::Red, TrafficLight::Green, TrafficLight::Yellow, ) } // solution 2 fn sum_u32(xs: &[u32]) -> Option { xs.iter().try_fold(0u32, |acc, &x| acc.checked_add(x)) } fn _display_sum(array: &[u32]) { println!("Sum of {:?} = {:?}", array, sum_u32(array)) } macro_rules! display_sum { ( $( $array:expr ),* $(,)? ) => {{ $( let array : &[u32] = $array; println!("Sum of {:?} = {:?}", array, sum_u32(array)); )* }}; } fn solution2() { display_sum!( &[], &[0], &[1], &[1, 2, 3, 4], &[std::u32::MAX], &[std::u32::MAX, 0], &[std::u32::MAX, 1], &[std::u32::MAX, 1, 2, 3, 4], ) } // solution 3 trait Shape { type Output; fn area(&self) -> Self::Output; } #[derive(Debug)] struct Square(T); #[derive(Debug)] struct Circle(T); #[derive(Debug)] struct Triangle(T, T); #[derive(Debug)] struct Rectangle(T, T); impl + Copy> Shape for Square { type Output = T; fn area(&self) -> Self::Output { self.0 * self.0 } } impl + Into + Copy> Shape for Circle { type Output = f64; fn area(&self) -> Self::Output { (self.0 * self.0).into() * std::f64::consts::PI } } impl + Copy> Shape for Rectangle { type Output = T; fn area(&self) -> Self::Output { self.0 * self.1 } } impl + Into + Copy> Shape for Triangle { type Output = f64; fn area(&self) -> Self::Output { (self.0 * self.1).into() * 0.5 } } /* fn display_shape(s: (impl Shape + std::fmt::Debug)){ println!("{:?}'s area is {}", s, s.area()) } */ // https://stackoverflow.com/questions/43143327/how-to-allow-optional-trailing-commas-in-macros macro_rules! display_shape { ($( $shape:expr),* $(,)?) => {{ $( println!("Area of {:?} = {}", $shape, $shape.area()); )* }}; } fn solution3() { display_shape!( Square(1), Square(0.2), Circle(1), Rectangle(1, 2), Rectangle(0.1, 0.2), Triangle(1, 2), Triangle(0.1, 0.2), ) } fn main() { println!("\n# solution 1"); solution1(); println!("\n# solution 2"); solution2(); println!("\n# solution 3"); solution3(); } // https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=363dea3ab64375f51511cf8a60f165c4