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 型別和相關函式中的邏輯,所有在其他地方使用它的地方都將是正確的。