Ferrugem - Tipos de Dados

O Type System representa os diferentes tipos de valores suportados pelo idioma. O Type System verifica a validade dos valores fornecidos, antes de serem armazenados ou manipulados pelo programa. Isso garante que o código se comporte conforme o esperado. O Type System permite ainda mais dicas de código e documentação automatizada.

Rust é uma linguagem tipificada estaticamente. Cada valor em Rust é de um determinado tipo de dados. O compilador pode inferir automaticamente o tipo de dados da variável com base no valor atribuído a ela.

Declare uma variável

Use o let palavra-chave para declarar uma variável.

fn main() {
   let company_string = "TutorialsPoint";  // string type
   let rating_float = 4.5;                 // float type
   let is_growing_boolean = true;          // boolean type
   let icon_char = '♥';                    //unicode character type

   println!("company name is:{}",company_string);
   println!("company rating on 5 is:{}",rating_float);
   println!("company is growing :{}",is_growing_boolean);
   println!("company icon is:{}",icon_char);
}

No exemplo acima, o tipo de dados das variáveis ​​será inferido dos valores atribuídos a elas. Por exemplo, Rust atribuirá tipo de dados de string para a variável company_string , tipo de dados float para rating_float , etc.

O println! macro leva dois argumentos -

  • Uma sintaxe especial {} , que é o espaço reservado
  • O nome da variável ou uma constante

O placeholder será substituído pelo valor da variável

A saída do snippet de código acima será -

company name is: TutorialsPoint
company rating on 5 is:4.5
company is growing: true
company icon is: ♥

Tipos escalares

Um tipo escalar representa um único valor. Por exemplo, 10,3.14, 'c'. A ferrugem tem quatro tipos escalares primários.

  • Integer
  • Floating-point
  • Booleans
  • Characters

Aprenderemos sobre cada tipo em nossas seções subsequentes.

Inteiro

Um inteiro é um número sem um componente fracionário. Simplificando, o tipo de dados inteiro é usado para representar números inteiros.

Os inteiros podem ser classificados como assinados e não assinados. Inteiros com sinal podem armazenar valores negativos e positivos. Inteiros sem sinal só podem armazenar valores positivos. Uma descrição detalhada se os tipos inteiros são fornecidos abaixo -

Sr. Não. Tamanho Assinado Sem sinal
1 8 bits i8 u8
2 16 bits i16 u16
3 32 bits i32 u32
4 64 bits i64 u64
5 128 bits i128 u128
6 Arco isize usize

O tamanho de um inteiro pode ser arqueado . Isso significa que o tamanho do tipo de dados será derivado da arquitetura da máquina. Um número inteiro cujo tamanho é arch será de 32 bits em uma máquina x86 e 64 bits em uma máquina x64. Um inteiro de arco é usado principalmente para indexar algum tipo de coleção.

Ilustração

fn main() {
   let result = 10;    // i32 by default
   let age:u32 = 20;
   let sum:i32 = 5-15;
   let mark:isize = 10;
   let count:usize = 30;
   println!("result value is {}",result);
   println!("sum is {} and age is {}",sum,age);
   println!("mark is {} and count is {}",mark,count);
}

O resultado será como fornecido abaixo -

result value is 10
sum is -10 and age is 20
mark is 10 and count is 30

O código acima retornará um erro de compilação se você substituir o valor de idade por um valor de ponto flutuante.

Intervalo Inteiro

Cada variante com sinal pode armazenar números de - (2 ^ (n-1) a 2 ^ (n-1) -1 , onde n é o número de bits que a variante usa. Por exemplo, i8 pode armazenar números de - (2 ^ 7) a 2 ^ 7 -1 - aqui substituímos n por 8.

Cada variante sem sinal pode armazenar números de 0 a (2 ^ n) -1 . Por exemplo, u8 pode armazenar números de 0 a 2 ^ 7 , que é igual a 0 a 255.

Estouro de inteiro

Um estouro de número inteiro ocorre quando o valor atribuído a uma variável inteira excede o intervalo definido por Rust para o tipo de dados. Vamos entender isso com um exemplo -

fn main() {
   let age:u8 = 255;

   // 0 to 255 only allowed for u8
   let weight:u8 = 256;   //overflow value is 0
   let height:u8 = 257;   //overflow value is 1
   let score:u8 = 258;    //overflow value is 2

   println!("age is {} ",age);
   println!("weight is {}",weight);
   println!("height is {}",height);
   println!("score is {}",score);
}

O intervalo válido da variável u8 sem sinal é de 0 a 255. No exemplo acima, as variáveis ​​são atribuídas a valores maiores que 255 (limite superior para uma variável inteira em Rust). Na execução, o código acima retornará um aviso -warning − literal out of range for u8para peso, altura e variáveis ​​de pontuação. Os valores de estouro após 255 começarão em 0, 1, 2, etc. A saída final sem aviso é mostrada abaixo -

age is 255
weight is 0
height is 1
score is 2

Flutuador

Tipo de dados flutuante em Rust pode ser classificado como f32 e f64. O tipo f32 é um float de precisão simples e f64 tem precisão dupla. O tipo padrão é f64. Considere o exemplo a seguir para entender mais sobre o tipo de dados float.

fn main() {
   let result = 10.00;        //f64 by default
   let interest:f32 = 8.35;
   let cost:f64 = 15000.600;  //double precision
   
   println!("result value is {}",result);
   println!("interest is {}",interest);
   println!("cost is {}",cost);
}

A saída será como mostrado abaixo -

interest is 8.35
cost is 15000.6

Fundição Automática

A fundição automática não é permitida em Rust. Considere o seguinte trecho de código. Um valor inteiro é atribuído à variável floatinterest.

fn main() {
   let interest:f32 = 8;   // integer assigned to float variable
   println!("interest is {}",interest);
}

O compilador lança um mismatched types error conforme indicado abaixo.

error[E0308]: mismatched types
   --> main.rs:2:22
   |
 2 | let interest:f32=8;
   |    ^ expected f32, found integral variable
   |
   = note: expected type `f32`
      found type `{integer}`
error: aborting due to previous error(s)

Separador de Número

Para facilitar a leitura de números grandes, podemos usar um separador visual _ sublinhado para separar os dígitos. Isso é 50.000 pode ser escrito como 50_000. Isso é mostrado no exemplo abaixo.

fn main() {
   let float_with_separator = 11_000.555_001;
   println!("float value {}",float_with_separator);
   
   let int_with_separator = 50_000;
   println!("int value {}",int_with_separator);
}

O resultado é dado abaixo -

float value 11000.555001
int value 50000

boleano

Os tipos booleanos têm dois valores possíveis - verdadeiro ou falso . Use obool palavra-chave para declarar uma variável booleana.

Ilustração

fn main() {
   let isfun:bool = true;
   println!("Is Rust Programming Fun ? {}",isfun);
}

A saída do código acima será -

Is Rust Programming Fun ? true

Personagem

O tipo de dados de caractere em Rust suporta números, alfabetos, Unicode e caracteres especiais. Use ocharpalavra-chave para declarar uma variável do tipo de dados de caractere. O tipo de char de Rust representa um valor escalar Unicode, o que significa que pode representar muito mais do que apenas ASCII. Valores escalares Unicode variam deU+0000 para U+D7FF e U+E000 para U+10FFFF inclusive.

Vamos considerar um exemplo para entender mais sobre o tipo de dados Character.

fn main() {
   let special_character = '@'; //default
   let alphabet:char = 'A';
   let emoji:char = '';
   
   println!("special character is {}",special_character);
   println!("alphabet is {}",alphabet);
   println!("emoji is {}",emoji);
}

A saída do código acima será -

special character is @
alphabet is A
emoji is