1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
/// # 抽象类型:Box(装箱)抽象类型 之 trait对象 /// /// Base usage: /// /// ``` /// #[derive(Debug)] /// struct Foo; /// trait Bar { /// fn baz(&self); /// } /// impl Bar for Foo { /// fn baz(&self) { println!("{:?}", self) } /// } /// fn static_dispatch<T>(t: &T) where T:Bar { /// t.baz(); /// } /// fn dynamic_dispatch(t: &Bar) { /// t.baz(); /// } /// let foo = Foo; /// static_dispatch(&foo); /// dynamic_dispatch(&foo); /// ``` pub fn trait_object() { #[derive(Debug)] struct Foo; trait Bar { fn baz(&self); } impl Bar for Foo { fn baz(&self) { println!("{:?}", self) } } fn static_dispatch<T>(t: &T) where T:Bar { t.baz(); } fn dynamic_dispatch(t: &Bar) { t.baz(); } let foo = Foo; static_dispatch(&foo); dynamic_dispatch(&foo); } /// # 抽象类型: impl Trait unbox存在类型 (Rust 2018) /// /// Base usage: 重构第二章中trait的示例 /// /// ``` /// use std::fmt::Debug; /// trait Fly { /// fn fly(&self) -> bool; /// } /// #[derive(Debug)] /// struct Duck; /// #[derive(Debug)] /// struct Pig; /// impl Fly for Duck { /// fn fly(&self) -> bool { /// return true; /// } /// } /// impl Fly for Pig { /// fn fly(&self) -> bool { /// return false; /// } /// } /// fn fly_static(s: impl Fly+Debug) -> bool { /// s.fly() /// } /// fn can_fly(s: impl Fly+Debug) -> impl Fly { /// if s.fly(){ /// println!("{:?} can fly", s); /// }else{ /// println!("{:?} can't fly", s); /// } /// s /// } /// fn dyn_can_fly(s: impl Fly+Debug+'static) -> Box<dyn Fly> { /// if s.fly(){ /// println!("{:?} can fly", s); /// }else{ /// println!("{:?} can't fly", s); /// } /// Box::new(s) /// } /// let pig = Pig; /// assert_eq!(fly_static(pig), false); // 静态分发 /// let pig = Pig; /// can_fly(pig); // 静态分发 /// let duck = Duck; /// assert_eq!(fly_static(duck), true); // 静态分发 /// let duck = Duck; /// can_fly(duck); // 静态分发 /// let duck = Duck; /// dyn_can_fly(duck); // 动态分发 /// ``` /// /// Base usage: 错误示范 /// /// ``` /// use std::ops::Add; /// // 以下多个参数的情况,虽然同时指定了impl Add<T, Output=T>类型, /// // 但是它们并不是同一个类型,因为这是抽象类型。 /// // 所以编译会出错: mismatched types /// fn sum<T>(a: impl Add<T, Output=T>, b: impl Add<T, Output=T>) -> T{ /// a + b /// } /// ``` /// /// Base usage: 正确 /// /// ``` /// use std::ops::Add; /// // 只能用于单个参数 /// fn hello<T>(a: impl Add<T, Output=T>) -> impl Add<T, Output=T>{ /// a /// } /// ``` pub fn impl_trait(){ use std::fmt::Debug; pub trait Fly { fn fly(&self) -> bool; } #[derive(Debug)] struct Duck; #[derive(Debug)] struct Pig; impl Fly for Duck { fn fly(&self) -> bool { return true; } } impl Fly for Pig { fn fly(&self) -> bool { return false; } } fn fly_static(s: impl Fly+Debug) -> bool { s.fly() } fn can_fly(s: impl Fly+Debug) -> impl Fly { if s.fly(){ println!("{:?} can fly", s); }else{ println!("{:?} can't fly", s); } s } fn dyn_can_fly(s: impl Fly+Debug+'static) -> Box<dyn Fly> { if s.fly(){ println!("{:?} can fly", s); }else{ println!("{:?} can't fly", s); } Box::new(s) } let pig = Pig; assert_eq!(fly_static(pig), false); let duck = Duck; assert_eq!(fly_static(duck), true); let pig = Pig; can_fly(pig); let duck = Duck; can_fly(duck); let duck = Duck; dyn_can_fly(duck); }