跳转到内容

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);
 }

现在我们通过点后分配给它们的名字来引用结构体内的值,这应该对我们来说很有用,更令人难忘,并且在阅读时更容易理解。

下一个:枚举

华夏公益教科书