编辑:张汉东


返回多态类型

  1. use rand::{thread_rng, Rng};
  2. /// This is the trait that every die needs to implement to be... well... "rollable", right?
  3. pub trait Rollable {
  4. /// Roll the die
  5. fn roll() -> Self;
  6. /// Get the value from the latest roll
  7. fn val(&self) -> u8;
  8. }
  9. /// A generic function to roll a given die.
  10. pub fn roll<T: Rollable>() -> T {
  11. Rollable::roll() // <- Note that here `Rollable` is the current type for a given call!
  12. }
  13. /// A D6 die (6 faces): a roll will give you a `u8` in the `1..=6` range.
  14. #[derive(Debug)]
  15. pub struct D6(u8);
  16. impl Rollable for D6 {
  17. fn roll() -> D6 {
  18. D6 {
  19. 0: thread_rng().gen_range(1..=6),
  20. }
  21. }
  22. fn val(&self) -> u8 {
  23. self.0
  24. }
  25. }
  26. /// A D8 die (8 faces): a roll will give you a `u8` in the `1..=8` range.
  27. #[derive(Debug)]
  28. pub struct D8(u8);
  29. impl Rollable for D8 {
  30. fn roll() -> D8 {
  31. D8 {
  32. 0: thread_rng().gen_range(1..=8),
  33. }
  34. }
  35. fn val(&self) -> u8 {
  36. self.0
  37. }
  38. }
  39. #[derive(Debug)]
  40. struct Fake100(u8);
  41. impl Rollable for Fake100 {
  42. fn roll() -> Fake100 {
  43. Fake100 { 0: 100 } // <- forces it to roll 100
  44. }
  45. fn val(&self) -> u8 {
  46. self.0
  47. }
  48. }
  49. fn main() {
  50. // let's roll a D6
  51. let r: D6 = roll();
  52. println!("{:?}", r); // D6(3)
  53. // let's roll a D8
  54. let r: D8 = roll();
  55. println!("{:?}", r); // D8(3)
  56. println!("I bet I'll get a 100 this time!");
  57. let d: Fake100 = roll();
  58. println!("Look what I got: {}!", d.val()) // <- yeah this will always be 100
  59. }

也支持类型推断:

  1. fn try_dodge_attack(d6: D6, d8: D8) -> bool {
  2. d6.val() + d8.val() > 10
  3. }
  4. fn main() {
  5. let escaped = try_dodge_attack(roll(), roll());
  6. println!(
  7. "{}",
  8. match escaped {
  9. true => "You dogded!",
  10. false => "Ouch! The attack hit you!",
  11. }
  12. );
  13. }

来源

一个零开销链表的实现

下面代码实现了一个 持久性/不变性(Persistent / Immutable )的单向链表(Singly-linked)。

  1. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
  2. pub enum List<'a, T> {
  3. Node { data: T, next: &'a List<'a, T> },
  4. Tail,
  5. }
  6. impl<T> Default for List<'_, T> {
  7. fn default() -> Self {
  8. List::Tail
  9. }
  10. }
  11. impl<'a, T> List<'a, T> {
  12. pub fn add(&'a self, data: T) -> Self {
  13. List::Node { data, next: self }
  14. }
  15. pub fn rev_iter(&'a self, f: impl Fn(&'a T)) {
  16. if let List::Node { data, next } = self {
  17. next.rev_iter(&f);
  18. f(data);
  19. }
  20. }
  21. pub fn try_rev_iter<E, F>(&'a self, f: F) -> Result<(), E>
  22. where
  23. F: Fn(&'a T) -> Result<(), E>,
  24. {
  25. if let List::Node { data, next } = self {
  26. next.try_rev_iter(&f)?;
  27. f(data)?;
  28. }
  29. Ok(())
  30. }
  31. }
  32. pub struct ListIter<'a, T>(&'a List<'a, T>);
  33. impl<'a, T> IntoIterator for &'a List<'a, T> {
  34. type Item = &'a T;
  35. type IntoIter = ListIter<'a, T>;
  36. fn into_iter(self) -> Self::IntoIter {
  37. ListIter(self)
  38. }
  39. }
  40. impl<'a, T> Iterator for ListIter<'a, T> {
  41. type Item = &'a T;
  42. fn next(&mut self) -> Option<Self::Item> {
  43. match self.0 {
  44. List::Node { data, next } => {
  45. self.0 = next;
  46. Some(data)
  47. }
  48. List::Tail => None,
  49. }
  50. }
  51. }
  52. #[derive(Debug, Clone, PartialEq)]
  53. pub enum Value {
  54. Num(f64),
  55. Bool(bool),
  56. String(String),
  57. }
  58. #[derive(PartialEq)]
  59. pub enum ValueKind {
  60. Num,
  61. Bool,
  62. String,
  63. }
  64. impl Value {
  65. pub fn kind(&self) -> ValueKind {
  66. match self {
  67. Value::Num(_) => ValueKind::Num,
  68. Value::Bool(_) => ValueKind::Bool,
  69. Value::String(_) => ValueKind::String,
  70. }
  71. }
  72. }
  73. #[derive(Debug, Clone)]
  74. pub enum Expr {
  75. Value(Value),
  76. Variable(String),
  77. UnExpr(UnExprKind, Box<Expr>),
  78. BinExpr(BinExprKind, Box<(Expr, Expr)>),
  79. Define(String, Box<(Expr, Expr)>),
  80. IfThenElse(Box<(Expr, Expr, Expr)>),
  81. }
  82. #[derive(Debug, Copy, Clone)]
  83. pub enum UnExprKind {
  84. Not,
  85. Neg,
  86. }
  87. #[derive(Debug, PartialEq, Copy, Clone)]
  88. pub enum BinExprKind {
  89. // Arithmetic
  90. Add,
  91. Sub,
  92. Mul,
  93. Div,
  94. // Logic
  95. And,
  96. Or,
  97. Equals,
  98. NotEquals,
  99. }
  100. type Variables<'a> = List<'a, (String, Value)>;
  101. pub fn eval(vars: &Variables<'_>, expr: Expr) -> Option<Value> {
  102. match expr {
  103. Expr::Value(val) => Some(val),
  104. Expr::Variable(var) => vars
  105. .into_iter()
  106. .find(|&(v, _)| *v == var)
  107. .map(|(_, val)| val.clone()),
  108. Expr::UnExpr(kind, expr) => {
  109. eval_unary(kind, vars, *expr)
  110. }
  111. Expr::BinExpr(kind, exprs) => {
  112. eval_binary(kind, vars, exprs.0, exprs.1)
  113. }
  114. Expr::Define(name, exprs) => {
  115. let value = eval(vars, exprs.0)?;
  116. let vars = vars.add((name, value));
  117. eval(&vars, exprs.1)
  118. }
  119. Expr::IfThenElse(exprs) => {
  120. if let Value::Bool(b) = eval(vars, exprs.0)? {
  121. eval(vars, if b { exprs.1 } else { exprs.2 })
  122. } else {
  123. None
  124. }
  125. }
  126. }
  127. }
  128. fn eval_unary(
  129. kind: UnExprKind,
  130. vars: &Variables<'_>,
  131. expr: Expr,
  132. ) -> Option<Value> {
  133. let val = eval(vars, expr)?;
  134. match (kind, val) {
  135. (UnExprKind::Not, Value::Bool(b)) => {
  136. Some(Value::Bool(!b))
  137. }
  138. (UnExprKind::Neg, Value::Num(n)) => Some(Value::Num(-n)),
  139. _ => None,
  140. }
  141. }
  142. fn eval_binary(
  143. kind: BinExprKind,
  144. vars: &Variables<'_>,
  145. lhs: Expr,
  146. rhs: Expr,
  147. ) -> Option<Value> {
  148. let lhs = eval(vars, lhs)?;
  149. match kind {
  150. BinExprKind::Add => {
  151. if let Value::Num(lhs) = lhs {
  152. if let Value::Num(rhs) = eval(vars, rhs)? {
  153. return Some(Value::Num(lhs + rhs));
  154. }
  155. }
  156. None
  157. }
  158. BinExprKind::Sub => {
  159. if let Value::Num(lhs) = lhs {
  160. if let Value::Num(rhs) = eval(vars, rhs)? {
  161. return Some(Value::Num(lhs - rhs));
  162. }
  163. }
  164. None
  165. }
  166. BinExprKind::Mul => {
  167. if let Value::Num(lhs) = lhs {
  168. if let Value::Num(rhs) = eval(vars, rhs)? {
  169. return Some(Value::Num(lhs * rhs));
  170. }
  171. }
  172. None
  173. }
  174. BinExprKind::Div => {
  175. if let Value::Num(lhs) = lhs {
  176. if let Value::Num(rhs) = eval(vars, rhs)? {
  177. return Some(Value::Num(lhs / rhs));
  178. }
  179. }
  180. None
  181. }
  182. BinExprKind::And => {
  183. if let Value::Bool(lhs) = lhs {
  184. if !lhs {
  185. return Some(Value::Bool(false));
  186. }
  187. if let Value::Bool(rhs) = eval(vars, rhs)? {
  188. return Some(Value::Bool(rhs));
  189. }
  190. }
  191. None
  192. }
  193. BinExprKind::Or => {
  194. if let Value::Bool(lhs) = lhs {
  195. if lhs {
  196. return Some(Value::Bool(true));
  197. }
  198. if let Value::Bool(rhs) = eval(vars, rhs)? {
  199. return Some(Value::Bool(rhs));
  200. }
  201. }
  202. None
  203. }
  204. BinExprKind::Equals => {
  205. let rhs = eval(vars, rhs)?;
  206. if lhs.kind() == rhs.kind() {
  207. Some(Value::Bool(lhs == rhs))
  208. } else {
  209. None
  210. }
  211. }
  212. BinExprKind::NotEquals => {
  213. let rhs = eval(vars, rhs)?;
  214. if lhs.kind() == rhs.kind() {
  215. Some(Value::Bool(lhs != rhs))
  216. } else {
  217. None
  218. }
  219. }
  220. }
  221. }

来源