Rust 新手程序员/基本数学测试程序/特征和显示
外观
< Rust 新手程序员 | 基本数学测试程序
Rust 中很少有魔法。我们之前学过的很多东西,以及之前使用过的很多东西,都可以在我们的代码中重新实现。我们希望在我们的程序中使用“{}”来直接显示运算符。
我们希望在 print_question() 中编写以下内容
fn print_question(num1: i32, num2: i32, operator: Operator) { println!("What is {} {} {}?", num1, operator, num2); }
然而,如果我们尝试运行它,我们会得到以下消息
error[E0277]: `Operator` doesn't implement `std::fmt::Display`
Rust 中 println!() 之类的函数的工作原理是,当它看到“{}”时,它会检查逗号后的对应对象是否实现了名为“Display”的“特征”。特征就像类型上的标记,表明它具有可以使用的某些方法。
如果我们查看 std::fmt::Display 文档,我们会发现该特征具有
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>
我们必须记住,这一切都在 std::fmt 下,所以我们必须在每个类型之前添加它。很多代码看起来很奇怪,但本质上我们必须编写一个与之匹配的函数,我们可以使用宏 write!() 来简化操作,如下所示
impl std::fmt::Display for Operator { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "+") } }
std::fmt::Result 本身是 Result<(), Error> 的简写。同样,每个东西前面的 std::fmt:: 也很繁琐。我们可以这样做
use std::fmt;
放在顶部,并修改 Display 特征的实现,如下所示
impl fmt::Display for Operator { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "+") } }
use 语句意味着,每当代码遇到 fmt 时,它就会假定它是 std::fmt。这有助于减少我们要编写的代码量,但如果我们有 fmt 的实例,也可能很危险,因为它无法区分。对于我们来说,这不太可能发生,因此我们可以放心地进行此更改。我们不必把它放在顶部,但通常情况下,我们希望将所有 use 语句放在同一个地方。也就是说,如果我们现在运行程序,我们会得到
What is 35 + 23?
糟糕,我们没有检查它是哪个运算符,现在让我们修复它
impl fmt::Display for Operator { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Operator::Addition => write!(f, "+"), Operator::Subtraction => write!(f, "-"), } } }
现在如果我们运行程序,我们会得到
What is 35 - 23?
这就是我们想要的结果。
所有这些看起来可能有点复杂,但这样做有一些好处
- 重用,我们现在可以轻松地在其他地方打印出运算符
- 分解问题,我们不希望所有内容都在同一个函数或同一个地方。这样一来,Operator 类型和功能就可以与程序的其他部分分离。
- 易于编辑,因为所有内容都在同一个地方,我们只需要更改 Operator 类型和相关函数中的逻辑,所有在其他地方使用它的地方都将是正确的。