fn main() {
    
    {
        pub trait Iterator {
            type Item;
            fn next(&mut self) -> Option<Self::Item>;
        }
    }
    
    {
        pub trait Iterator<T>{
            fn next(&mut self) -> Option<T>;
        }
    }


    // 操作符重载
    {
        use std::ops::Add;

        #[derive(Debug, PartialEq)]
        struct Point {
            x: i32,
            y: i32,
        }

        impl Add for Point {
            type Output = Point;

            fn add(self, other: Point) -> Point {
                Point {
                    x: self.x + other.x,
                    y: self.y + other.y,
                }
            }
        }

        println!("{:?}", Point{x:1, y:2} + Point{x:3, y:4});
    }


    // 操作符重载 
    {
        use std::ops::Add;

        struct Millimeters(u32);
        struct Meters(u32);

        impl Add<Meters> for Millimeters {
            type Output = Millimeters;

            fn add(self, other: Meters) -> Millimeters {
                Millimeters(self.0 + (other.0 * 1000))
            }
        }
    }

    {
        trait Pilot {
            fn fly(&self);
        }

        trait Wizard {
            fn fly(&self);
        }

        struct Human;

        impl Pilot for Human {
            fn fly(&self) {
                println!("飞行员开始操作");
            }
        }
        
        impl Wizard for Human {
            fn fly(&self) {
                println!("巫师腾空");
            }
        }

        impl Human {
            fn fly(&self){
                println!("挥舞手臂，无济于事");
            }
        }

        {
            let person = Human;
            person.fly();
        }
        
        {
            let person = Human;
            Pilot::fly(&person);
            Wizard::fly(&person);
            person.fly();
        }
    }


    {
        trait Animal {
            fn baby_name() -> String;
        }

        struct Dog;

        impl Dog {
            fn baby_name() -> String {
                String::from("来自 `impl Dog` 的宝宝名")
            }
        }

        impl Animal for Dog {
            fn baby_name() -> String {
                String::from("来自 `impl Animal for Dog` 的宝宝名")
            }
        }

        {
            println!("Dog::baby_name() \n     {}", Dog::baby_name());
            println!("<Dog as Animal>::baby_name()\n    {}", <Dog as Animal>::baby_name());
        }
    }

    {
        use std::fmt;

        struct Wrapper(Vec<String>);

        impl fmt::Display for Wrapper {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result{
                write!(f, "[{}]", self.0.join(", "))
            }
        }

        let w = Wrapper(vec![String::from("hello"), String::from("world"), String::from("2333")]);
        println!("w={}", w);
    }

}
