ex7: tuple

ex5 中我们介绍了基本数据类型,ex7 中我们开始见到第一个复合数据类型:元组(tuple)

复合数据类型一般可以由多个基本数据类型组合而成,并且有各自的特点。元组的基本样子是由小括号和逗号组合成的一组元素:(1u8,1.0f64, true, 'a'),里面的元素种类不限,可以进行元组的嵌套。

元组可以认为是一种可以容纳若干个数量一定的元素的容器,其长度不能改变,但是储存的数据可以改变。

更多的细节可以查看代码以及代码说明

代码

fn main() {
    // 使用小括号和逗号创建元组
    // 元组中可以有很多不同类型的元素,但是对于每一个位置,类型都是确定的,无法修改类型
    let mix_tuple = (1u8, 2u16, 3u32, 4u64,
        -1i8, -2i16, -3i32, -4i64,
        0.1f32, 0.2f64,
        'a', true, "Hello", (1,2));

    let vector: (i32, i32) = (1, 2); // 你可以这样标注元组的类型
    // 访问元组的元素需要使用元组索引
    // 从零开始
    println!("x: {}, y: {}", vector.0, vector.1);

    // #1
    // 可以使用 let 将元组中的内容逐个赋值给别的变量
    let (x, y) = vector;
    println!("x: {}, y: {}", x, y);
    let (first, .., hello, last) = mix_tuple;
    println!("first: {}, hello: {}", first, hello);


    // #2
    // 下面这句是错误的,我们已经帮你注释掉了
    // println!("short tuple {}", vector);
    // 元组可以打印,但是必须使用这种形式
    println!("short tuple {:?}", vector);
    // 下面这句是错误的,我们已经帮你注释掉了
    // println!("too long tuple {:?}", mix_tuple);

    // 一个元素也可以是元组
    // 不过注意必须要有一个逗号
    // 否则会被认为是一个表达式 #3
    let single_integer: i32 = (1);
    let single_tuple: (i32,) = (1,);
    println!("integer: {}", single_integer);
    // !error! 下面这句是错误的!
    // 上面可以打印,说明其类型为整型
    println!("single_tuple: {}", single_tuple);

    // !error! 下面这句是错误的!
    // 我们定义的 vector 变量是不可变的(之后会说明)
    vector.1 = 1;

    let mut mut_vector = (1, 2i32); // 这是一个可变的 vector
    mut_vector.0 = 1;
    // !error! 下面这句是错误的!
    // 虽然你可以改变元组中的值,但是你不能改变它的类型 #4
    mut_vector.1 = 1.0;
    println!("mut_vector: {:?}", mut_vector);
}

代码说明

代码中使用#num的方法标注了对应的代码说明部分

#1

你可以像这样把一个元组拆分成几个部分,并且把值分别赋给不同的变量。这不会影响到元组中元素的所有权,它们仅仅是复制了一份新的数据。(有关所有权我们会在之后详细说明)

可以看到我们可以使用..作为占位符来进行值的分配

#2

至于打印的时候{:?}是什么含义,我们会在 ex11 中详细地说明。目前你可以认为只有基本数据类型可以简单地使用{}进行格式化输出,而 tuple 是复合数据类型,所以它不能直接输出。如果想要输出必须使用{:?}指定进行 Debug 输出。

但是当元组的长度达到 13 的时候,Debug 输出也不好用了。至于为什么恰好是 13 ,说不定是因为数字不够吉利吧。

#3

不能使用(1)指定元组的原因是因为编译器认为你想要表达的是数学表达式:一个具有小括号的数字一。为了避免编译器发生歧义,所以规定了元组必须要有一个逗号才能被认为是元组(因为数学表达式中不会出现逗号)。

#4

你如果这样写:

let mut mut_vector = (1,2);
mut_vector.0 = 128u32;

这不会有问题。不过这不是因为你修改了元组中第一项的值,而是因为编译器推断出你元组中的数据储存的类型实际上是u32,你并不能在后续的操作中修改它的类型。

本节总结

在这一节中我们介绍了第一种复合数据类型:tuple。这个类型的使用有一定的技巧,需要对使用的方法较为熟练地掌握。因为这个基本的数据类型会在未来的structenum以及一些其他的内容中进行使用,所以把 tuple 的基础用法弄熟练了是一件很重要的事情。

你应该对下面的内容有所掌握:

  1. 元组(tuple)的创建、元素访问、解构、打印

你应该对下面的内容有所了解:

  1. 元组中的每个元素的类型是固定的

  2. 元组的打印需要使用{:?}

  3. 使用mut标注的元组可以进行修改

参考资料

Rust By Example: Tuples

最后更新于