Tuplas

Uma tupla é uma coleção que armazena valores de vários tipos diferentes. Tuplas são criadas usando parênteses (). Cada tupla é um valor independente por si só, sua anotação de tipo é escrita como (T1, T2, ...), onde T1 e T2 representam o tipo de cada membro interno da tupla. Funções podem retornar vários resultados usando tuplas, pois uma única tupla pode conter uma quantidade arbitrária de dados.

1 Usar tuplas como parâmetros e valores de retorno de funções

// Tuplas podem ser usadas tanto como parâmetros de entrada quanto valores retornados por uma função
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // let permite desestruturar membros da tupla e vinculá-los a variáveis separadas
    let (int_param, bool_param) = pair;
    // Retorna uma nova tupla com a ordem trocada
    (bool_param, int_param)
}

fn main(){
    // (12, true) é uma tupla binária completa, passada como um único parâmetro
	let res = reverse((12, true));
	// Usar o índice .0 para pegar o primeiro elemento da tupla retornada
	println!("{}", res.0);
}Code language: JavaScript (javascript)

Resultado da compilação e execução

E:\rustdemo\demo>rustc demo.rs

E:\rustdemo\demo>demo
trueCode language: JavaScript (javascript)

2 Definição de Estrutura de Tupla (Tuple Struct)

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main(){
    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix);
}Code language: PHP (php)

Estrutura de tupla: o nome da estrutura vem seguido diretamente por parênteses + lista de tipos, sem campos nomeados; os elementos só são diferenciados pela ordem;

A macro derivada #[derive(Debug)]: implementa automaticamente a trait Debug para a estrutura, permitindo imprimir informações de depuração com {:?};

Matrix(f32,f32,f32,f32) é essencialmente uma tupla especial que envolve quatro números de ponto flutuante.

Um aviso aparecerá durante a execução e pode ser ignorado

E:\rustdemo\demo>rustc demo.rs
warning: fields `0`, `1`, `2`, and `3` are never read
 --> demo.rs:2:15
  |
2 | struct Matrix(f32, f32, f32, f32);
  |        ------ ^^^  ^^^  ^^^  ^^^
  |        |
  |        fields in this struct
  |
  = help: consider removing these fields
  = note: `Matrix` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

warning: 1 warning emitted


E:\rustdemo\demo>demo
Matrix(1.1, 1.2, 2.1, 2.2)Code language: JavaScript (javascript)

3 Tuplas longas com tipos mistos + pegar valores por índice

Veja o exemplo primeiro

fn main(){

    // Tupla longa contendo vários tipos de dados diferentes
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Valores internos podem ser extraídos usando índices da tupla
    println!("Long tuple first value: {}", long_tuple.0);
    println!("Long tuple second value: {}", long_tuple.1);
}Code language: JavaScript (javascript)

Permite armazenar dados de tipos diferentes ao mesmo tempo (inteiros sem sinal, inteiros com sinal, floats, caracteres e booleanos podem coexistir);

Sintaxe de índice de tupla: variável_tupla.número, índices começam em 0;

  • .0 pega o primeiro elemento,
  • .1 pega o segundo elemento;
  • e assim por diante…

Índices só aceitam literais numéricos fixos; variáveis não podem ser usadas como índice.

Parte não organizada abaixo——

2. Definição de Estrutura de Tupla (Tuple Struct)


// A estrutura abaixo é para exercícios após a aula
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
Code language: PHP (php)

Pontos de conhecimento complementares

  1. Estrutura de tupla: o nome da estrutura é seguido por parênteses com lista de tipos dentro. Não há nomes de campos, os elementos são diferenciados apenas pela ordem;
  2. A macro derivada #[derive(Debug)]: implementa automaticamente a trait Debug para a estrutura, permitindo impressão de depuração com {:?};
  3. Matrix(f32,f32,f32,f32) é essencialmente uma tupla especial que envolve quatro números de ponto flutuante.

Exemplo completo abaixo

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main() {
    // 1. Criar instância
    let mat = Matrix(1.0, 2.0, 3.0, 4.0);

    // 2. Imprimir (é preciso #[derive(Debug)] para usar {:?})
    println!("Instância da matriz: {:?}", mat);

    // 3. Acessar elementos internos via .índice
    let a = mat.0;
    let b = mat.1;
    let c = mat.2;
    let d = mat.3;
    println!("a={}, b={}, c={}, d={}", a, b, c, d);

    // 4. Extrair valores por desestruturação
	// Matrix(m0, m1, m2, m3) é um padrão de desestruturação. m0/m1/m2/m3 são nomes de variáveis temporais definidos por você, que recebem os valores dos quatro membros da tupla dentro da estrutura.
    let Matrix(m0, m1, m2, m3) = mat;
    println!("Desestruturação:{} {} | {} {}", m0, m1, m2, m3);
	

    // 5. Matriz mutável, modificar elementos com mut
    let mut mat_mut = Matrix(0.0, 0.0, 0.0, 0.0);
    mat_mut.0 = 10.0;
    mat_mut.3 = 99.0; // Valores podem ser alterados
    println!("Matriz mutável: {:?}", mat_mut);
}Code language: PHP (php)

Resultado da execução

E:\rustdemo\demo>demo
Instância da matriz: Matrix(1.0, 2.0, 3.0, 4.0)
a=1, b=2, c=3, d=4
Desestruturação:1 2 | 3 4
Matriz mutável: Matrix(10.0, 0.0, 0.0, 99.0)

3 Tuplas longas com tipos mistos + pegar valores por índice

fn main() {
 
    // Tupla longa contendo vários tipos de dados diferentes
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using tuple indexing.
    // Valores internos podem ser extraídos usando índices da tupla
    println!("Long tuple first value: {}", long_tuple.0);
    println!("Long tuple second value: {}", long_tuple.1);
}
Code language: JavaScript (javascript)

Resultado da execução

E:\rustdemo\demo>demo
Long tuple first value: 1
Long tuple second value: 2

Resumo

  1. Característica principal das tuplas: permite armazenar dados de tipos diferentes ao mesmo tempo (inteiros sem sinal, inteiros com sinal, floats, caracteres e booleanos podem coexistir);
  2. Sintaxe de índice de tupla: variável_tupla.número, índices começam em 0;
    • .0 pega o primeiro elemento,
    • .1 pega o segundo elemento;
  3. Índices só aceitam literais numéricos fixos; variáveis não podem ser usadas como índice.

4 Tuplas aninhadas

fn main() {
 
    // Os membros de uma tupla também podem ser tuplas, aninhamento é suportado
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

 
    // Tuplas suportam impressão de depuração
    println!("tuple of tuples: {:?}", tuple_of_tuples);
	
	// Usar dois pontos seguidos para imprimir valores
	println!("tuple of tuples: {:?}", tuple_of_tuples.0.1); // Imprime 2
}
Code language: JavaScript (javascript)

Saída

E:\rustdemo\demo>demo
tuple of tuples: ((1, 2, 2), (4, -1), -2)
tuple of tuples: 2

Resumo

  1. Suporta aninhamento de tuplas em vários níveis; os elementos da tupla externa podem ser subtuplas;
  2. Tuplas com ≤12 elementos implementam automaticamente a trait Debug, o especificador de formatação {:?} pode imprimir todo o conteúdo diretamente.

5 Restrição de impressão para tuplas muito longas (erro de compilação)


   fn main() {
 
    // Tuplas com mais de 12 elementos não podem ser impressas diretamente com Debug
    let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
    println!("Too long tuple: {:?}", too_long_tuple);
    // Dica: comente as duas linhas acima para ver o erro do compilador
}
Code language: JavaScript (javascript)

Erro de compilação

E:\rustdemo\demo>rustc demo.rs
error[E0277]: `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` doesn't implement `Debug`
 --> demo.rs:5:38
  |
5 |     println!("Too long tuple: {:?}", too_long_tuple);
  |                               ----   ^^^^^^^^^^^^^^ `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` cannot be formatted using `{:?}` because it doesn't implement `Debug`
  |                               |
  |                               required by this formatting parameter
  |
  = help: the trait `Debug` is not implemented for `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})`
  = help: the following other types implement trait `Debug`:
            ()
            (A, Z, Y, X, W, V, U, T)
            (B, A, Z, Y, X, W, V, U, T)
            (C, B, A, Z, Y, X, W, V, U, T)
            (D, C, B, A, Z, Y, X, W, V, U, T)
            (E, D, C, B, A, Z, Y, X, W, V, U, T)
            (T,)
            (U, T)
          and 5 others
  = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.Code language: PHP (php)

Resumo

A biblioteca padrão do Rust só deriva automaticamente a trait Debug para tuplas com 0~12 elementos;

Tuplas com mais de 12 elementos não têm implementação nativa de Debug, imprimir diretamente com {:?} causará falha na compilação.

Você pode apagar o número 13 acima e testar para ver se o erro desaparece

6 Chamar funções com parâmetros de tupla e observar o resultado trocado

// Tuplas podem ser usadas tanto como parâmetros de entrada quanto valores retornados por uma função
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // let permite desestruturar membros da tupla e vinculá-los a variáveis separadas
    let (int_param, bool_param) = pair;
    // Retorna uma nova tupla com a ordem trocada
    (bool_param, int_param)
}

fn main() {
 
    let pair = (1, true);
    println!("Pair is {:?}", pair);

    println!("The reversed pair is {:?}", reverse(pair)); // Chamar reverse para trocar a ordem
}Code language: JavaScript (javascript)

Resultado da execução

E:\rustdemo\demo>demo
Pair is (1, true)
The reversed pair is (true, 1)Code language: JavaScript (javascript)

Resumo

  1. Tuplas binárias normais podem ser passadas diretamente como argumentos para funções que aceitam tuplas;
  2. A função retorna uma tupla totalmente nova, a tupla original pair não é modificada.

7 Regra especial da vírgula para tuplas de um único elemento (ponto comum de erro)


   fn main() {
 
    // Ao criar uma tupla de um único elemento é obrigatório adicionar vírgula para diferenciar de literais comuns apenas envoltos por parênteses
    println!("One element tuple: {:?}", (5u32,)); 
    println!("Just an integer: {:?}", (5u32));

}Code language: JavaScript (javascript)

Resumo

  1. (5u32,): com vírgula no final, é uma tupla válida de um único elemento, tipo (u32,);
  2. (5u32): sem vírgula, equivale apenas ao número comum 5u32 envolto por parênteses, não é uma tupla;
  3. A vírgula é o único marcador que distingue tuplas de um elemento de expressões entre parênteses.

8 Desestruturação completa de tuplas com múltiplos elementos (veja acima)


    // Tuplas podem ser totalmente desestruturadas para vincular várias variáveis de uma vez
    let tuple = (1, "hello", 4.5, true);

    let (a, b, c, d) = tuple;
    println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);
Code language: JavaScript (javascript)

Resumo

  1. Tuplas de qualquer comprimento podem ser totalmente desestruturadas; a quantidade de variáveis à esquerda deve combinar exatamente com a quantidade de elementos da tupla;
  2. Após desestruturação, cada variável corresponde ao valor da mesma posição na tupla e pode ser usada separadamente.

9 Instanciação de estrutura de tupla e impressão Debug

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main() {
 
    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix);

}Code language: PHP (php)

Resumo

  1. Sintaxe de instanciação de estrutura de tupla: NomeEstrutura(valor1, valor2, ...);
  2. Ao adicionar #[derive(Debug)], a estrutura suporta impressão de depuração via {:?}.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *