Tipos Escalares e Compostos
Os tipos escalares do Rust armazenam valores únicos. Tipos compostos - tuplas e arrays de tamanho fixo - agrupam valores com formas conhecidas estaticamente.
Receita
fn main() {
let count: u32 = 42;
let ratio: f64 = 3.14;
let ok: bool = true;
let ch: char = '✓';
let pair: (u32, &str) = (count, "itens");
let nums: [i32; 3] = [1, 2, 3];
println!("{count} {ratio} {ok} {ch} {:?} {:?}", pair, nums);
}Quando usar isso: Escolher o tipo primitivo ou agregado pequeno correto antes de recorrer a Vec ou structs personalizadas.
Exemplo de Trabalho
fn stats(values: [f64; 4]) -> (f64, f64) {
let sum: f64 = values.iter().sum();
let avg = sum / values.len() as f64;
(sum, avg)
}
fn main() {
let readings = [98.6, 99.1, 98.4, 99.0];
let (total, average) = stats(readings);
println!("soma={total:.2}, média={average:.2}");
}O que isso demonstra:
- Array de tamanho fixo passado por valor (copia 4
f64s na stack) - Tipo de retorno de tupla para múltiplos valores antes que uma struct seja justificada
as f64para conversão numérica explícita- Indexação de array com comprimento conhecido em tempo de compilação
Mergulho Profundo
Tipos Escalares em Resumo
| Tipo | Tamanho (típico) | Notas |
|---|---|---|
i32 / u32 | 4 bytes | Tipo de inteiro padrão |
i64 / u64 | 8 bytes | Timestamps, IDs |
f32 / f64 | 4 / 8 bytes | f64 é o float padrão |
bool | 1 byte | Apenas true ou false |
char | 4 bytes | Escalar Unicode, não apenas ASCII |
Literais de Inteiro e Overflow
let hex = 0xff_u8;
let bin = 0b1010_0110;
let wrapped = 255u8.wrapping_add(1); // 0Em builds de debug, o overflow causa um panic. Use wrapping_*, checked_* ou saturating_* quando o comportamento de overflow for importante.
Arrays vs Slices
let arr: [i32; 3] = [1, 2, 3];
let slice: &[i32] = &arr[1..];Arrays têm o comprimento no tipo. Slices são ponteiros "gordos" (ponteiro + comprimento) e podem referenciar arrays, Vec ou dados na stack.
Tuplas
let t = (1, "a", true);
let (a, b, c) = t;
assert_eq!(t.0, a);A tupla vazia () é o tipo unit - tipo de retorno de funções que não retornam nada significativo.
Armadilhas
- Assumir que
chartem um byte -charé UTF-32. Correção: Useu8para bytes brutos; iterestrcom.chars(). - Indexar além dos limites do array - Panic em tempo de execução em Rust seguro. Correção: Use
.get(i)para acesso opcional. - Misturar tipos de inteiros -
let x: i32 = 1i16;precisa de cast explícito. Correção: UseasouTryInto. - Igualdade de floats -
0.1 + 0.2 == 0.3é falso. Correção: Compare com épsilon ou use inteiros (centavos). - Arrays grandes na stack -
[u8; 1_000_000]pode estourar a stack. Correção: UseVecouBox<[T]>no heap.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Struct com campos nomeados | Tupla tem mais de 2-3 campos ou significado incerto | Coordenadas (x, y) únicas |
Vec<T> | Coleção com tamanho em tempo de execução | Comprimento é fixo e pequeno |
| Wrapper Newtype | Unidades distintas (Metros, Segundos) | Apenas matemática interna simples |
SmallVec / array | Geralmente pequeno, ocasionalmente grande | Dados sempre alocados no heap |
FAQs
Qual é o tipo de inteiro padrão?
i32 quando a inferência não tem outra restrição. Use sufixos explícitos (42u64) em APIs que precisam de uma largura específica.
O tamanho do array pode ser genérico?
Sim, com genéricos constantes: struct Buffer<const N: usize> { data: [u8; N] }.
Como inicializo um array com o mesmo valor?
let a = [0u8; 1024]; repete 0u8 1024 vezes. O elemento deve implementar Copy.
Bools são de um bit?
Não. bool é de 1 byte para alinhamento e endereçamento simples.
Tuplas podem implementar traits?
Apenas para aridades específicas através de implementações padrão (por exemplo, Clone para tuplas pequenas). Prefira structs para APIs públicas.
O que é `isize`?
Inteiro com sinal do tamanho do ponteiro. Use para indexação e resultados de len() (usize).
Como converto strings para números?
"42".parse::<i32>() retorna Result. Veja a seção de strings para FromStr.
Rust tem `null`?
Não. Use Option<T> para valores ausentes.
Posso comparar arrays?
Sim, se T: PartialEq. [1,2] == [1,2] funciona elemento a elemento.
Quando devo usar `f32`?
Kernels de GPU/matemática onde a largura de banda da memória é importante. Use f64 como padrão em outros lugares.
Relacionados
- Variáveis, Mutabilidade e Sombreamento - ligações e desestruturação
- Referências e Slices - tipos de slice em profundidade
- O Sistema de Tipos e Inferência - regras de inferência
- Noções Básicas de Structs - tipos de produto nomeados
Versões do Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.