跳轉到內容

Rust 新手程式設計指南 / 元組和結構體

100% developed
來自華夏公益教科書,開放的書籍,開放的世界

元組和結構體

[編輯 | 編輯原始碼]

假設我們想要從一個函式中返回多個值。舉個例子,讓我們建立一個函式,從一個數字向量中獲取最小值、最大值以及平均值是否小於某個閾值。我們不能返回一個向量或陣列,因為我們想要返回的第三個值將是一個布林值,而另外兩個將是整數,而向量和陣列只能儲存相同型別的值。因此,最簡單的解決方案是返回一個元組。

元組只是一組值,由 () 括號組織。所以我們的函式將類似於

 fn get_min_max_mean_below_threshold(input: Vec<i32>, threshold: i32) -> (i32, i32, bool) {
     //to do
 }

所以該函式接收一個輸入值的向量和一個閾值作為輸入,並返回一個包含兩個整數和一個布林值的元組作為輸出。將這些作為單個函式而不是三個單獨的函式的原因是,我們可以同時計算所有三個值,而只需遍歷數字一次。如果我們有三個單獨的函式,那麼遍歷所有數字三次會更慢。

 fn get_min_max_mean_below_threshold(input: Vec<i32>, threshold: f64) -> (i32, i32, bool) {
     let mut sum = 0;
     let mut min = i32::MAX;
     let mut max = i32::MIN;
 
     for index in 0..input.len() {
         let value = input[index];
         sum += value;
         if value < min {
             min = value;
         }
         if value > max { 
             max = value;
         }
     }

     let mean = sum as f64 / input.len() as f64;
     let mut below_threshold = false;
     if mean < threshold {
         below_threshold = true;
     }
     return (min, max, below_threshold);
 }

整個程式碼已包含在內,供您檢視、檢查和嘗試。需要注意的是,最小值和最大值必須先有一個值,因此它們最初被設定為最大值和最小值,因此向量中的幾乎任何值都會覆蓋它們。對於元組來說,最重要的是我們在最後透過將它放在 () 括號中來構造元組,並將其從函式中返回。順序很重要,因為我們使用它來從元組中獲取值。在我們的主函式中,有兩種方法可以獲取值。以下是第一種方法

 fn main() {
     let values = get_min_max_mean_below_threshold(vec![10, 3, 6, 2, 7, 14], 10.0);
     println!("The minimum is {}", values.0);
     println!("The maximum is {}", values.1);
     println!("Whether the mean was below the threshold was {}", values.2);
 }

請注意,我們在 println!() 中的文字中包含其他內容,以便為不同的值提供上下文。逗號後的值將插入 {} 所在的位置。我們透過引用元組中值的索引來從元組中獲取值,就像陣列從 0 開始一樣。但是,與陣列和向量不同,我們不能使用變數來獲取值,所以我們不能這樣做

 let index = 1;
 let value = values.index;
This will not work, if you want something like this you will want an array most likely. There is another way of getting values out of a tuple:
  fn main() {
     let (min, max, below_threshold) = get_min_max_mean_below_threshold(vec![10, 3, 6, 2, 7, 14], 10.0);
     println!("The minimum is {}", min);
     println!("The maximum is {}", max);
     println!("Whether the mean was below the threshold was {}", below_threshold);
 }

這稱為解構,因為我們模仿元組的結構,將值提取到充當任何其他變數的變數中。您可以選擇哪種選項來獲取值,可能取決於情況,選擇最適合的選項。

但是,這有一個明顯的缺點。假設我們還想獲取其他值,比如眾數或標準差(如果您不知道這些是什麼,沒關係)。一個包含太多值的元組很笨拙,因為我們必須記住所有值的順序。最好以更結構化的方式檢視一組資料的方法稱為結構體。我們像這樣構造/宣告一個結構體

 struct VectorValues {
     minimum: i32,
     maximum: i32,
     is_below_threshold: bool,
 }

由於這是一個宣告,我們只指定了將放入其中的型別。然後我們將獲取值的函式更改為

 fn get_min_max_mean_below_threshold(input: Vec<i32>, threshold: f64) -> VectorValues {
     //the inside is the same as above except for the last line
     let values = VectorValues {
         minimum: min,
         maximum: max,
         is_below_threshold: below_threshold,
     };
     return values;
 }

現在這意味著在我們的主函式中,我們可以這樣做

 fn main() {
     let values = get_min_max_mean_below_threshold(vec![10, 3, 6, 2, 7, 14], 10.0);
     println!("The minimum is {}", values.minimum);
     println!("The maximum is {}", values.maximum);
     println!("Whether the mean was below the threshold was {}", values.is_below_threshold);
 }

現在我們透過點後分配給它們的名字來引用結構體內的值,這應該對我們來說很有用,更令人難忘,並且在閱讀時更容易理解。

下一個:列舉

華夏公益教科書