Rust 新手程式設計指南 / 元組和結構體
假設我們想要從一個函式中返回多個值。舉個例子,讓我們建立一個函式,從一個數字向量中獲取最小值、最大值以及平均值是否小於某個閾值。我們不能返回一個向量或陣列,因為我們想要返回的第三個值將是一個布林值,而另外兩個將是整數,而向量和陣列只能儲存相同型別的值。因此,最簡單的解決方案是返回一個元組。
元組只是一組值,由 () 括號組織。所以我們的函式將類似於
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);
}
現在我們透過點後分配給它們的名字來引用結構體內的值,這應該對我們來說很有用,更令人難忘,並且在閱讀時更容易理解。