Rust - Tipos de datos

El sistema de tipos representa los diferentes tipos de valores admitidos por el idioma. El Type System verifica la validez de los valores proporcionados, antes de que sean almacenados o manipulados por el programa. Esto asegura que el código se comporte como se esperaba. Además, el Type System permite sugerencias de código más completas y documentación automatizada.

Rust es un lenguaje escrito estáticamente. Cada valor en Rust es de un determinado tipo de datos. El compilador puede inferir automáticamente el tipo de datos de la variable en función del valor que se le asigna.

Declarar una variable

Utilizar el let palabra clave para declarar una variable.

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

En el ejemplo anterior, el tipo de datos de las variables se deducirá de los valores que se les asignen. Por ejemplo, Rust asignará el tipo de datos de cadena a la variable company_string , el tipo de datos flotante a rating_float , etc.

¡El println! macro toma dos argumentos -

  • Una sintaxis especial {} , que es el marcador de posición
  • El nombre de la variable o una constante

El marcador de posición será reemplazado por el valor de la variable

La salida del fragmento de código anterior será:

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

Tipos escalares

Un tipo escalar representa un valor único. Por ejemplo, 10,3.14, 'c'. El óxido tiene cuatro tipos escalares principales.

  • Integer
  • Floating-point
  • Booleans
  • Characters

Aprenderemos sobre cada tipo en las secciones siguientes.

Entero

Un número entero es un número sin componente fraccionario. En pocas palabras, el tipo de datos entero se utiliza para representar números enteros.

Los enteros se pueden clasificar además como firmados y no firmados. Los enteros con signo pueden almacenar valores tanto negativos como positivos. Los enteros sin signo solo pueden almacenar valores positivos. A continuación, se ofrece una descripción detallada de los tipos de enteros:

No Señor. Talla Firmado No firmado
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 usar

El tamaño de un número entero puede ser arco . Esto significa que el tamaño del tipo de datos se derivará de la arquitectura de la máquina. Un número entero cuyo tamaño sea arch será de 32 bits en una máquina x86 y de 64 bits en una máquina x64. Un entero de arco se usa principalmente cuando se indexa algún tipo de colección.

Ilustración

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

La salida será la que se indica a continuación:

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

El código anterior devolverá un error de compilación si reemplaza el valor de age con un valor de punto flotante.

Rango de enteros

Cada variante con signo puede almacenar números de - (2 ^ (n-1) a 2 ^ (n-1) -1 , donde n es el número de bits que usa la variante. Por ejemplo, i8 puede almacenar números de - (2 ^ 7) a 2 ^ 7 -1 - aquí reemplazamos n con 8.

Cada variante sin firmar puede almacenar números del 0 al (2 ^ n) -1 . Por ejemplo, u8 puede almacenar números de 0 a 2 ^ 7 , que es igual a 0 a 255.

Desbordamiento de enteros

Un desbordamiento de enteros ocurre cuando el valor asignado a una variable de entero excede el rango definido por Rust para el tipo de datos. Entendamos esto con un ejemplo:

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

El rango válido de la variable u8 sin signo es de 0 a 255. En el ejemplo anterior, a las variables se les asignan valores superiores a 255 (límite superior para una variable entera en Rust). En la ejecución, el código anterior devolverá una advertencia:warning − literal out of range for u8para las variables de peso, altura y puntuación. Los valores de desbordamiento después de 255 comenzarán desde 0, 1, 2, etc. La salida final sin advertencia es como se muestra a continuación:

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

Flotador

El tipo de datos flotantes en Rust se puede clasificar como f32 y f64. El tipo f32 es un flotador de precisión simple y el f64 tiene doble precisión. El tipo predeterminado es f64. Considere el siguiente ejemplo para comprender más sobre el tipo de datos flotantes.

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

La salida será como se muestra a continuación:

interest is 8.35
cost is 15000.6

Casting de tipo automático

No se permite la fundición de tipo automático en Rust. Considere el siguiente fragmento de código. Se asigna un valor entero a la variable flotanteinterest.

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

El compilador arroja un mismatched types error como se indica a continuación.

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úmeros

Para facilitar la lectura de números grandes, podemos usar un separador visual _ guión bajo para separar dígitos. Eso es 50,000 se puede escribir como 50_000. Esto se muestra en el siguiente ejemplo.

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

La salida se da a continuación:

float value 11000.555001
int value 50000

Booleano

Los tipos booleanos tienen dos valores posibles: verdadero o falso . Utilizar elbool palabra clave para declarar una variable booleana.

Ilustración

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

La salida del código anterior será:

Is Rust Programming Fun ? true

Personaje

El tipo de datos de caracteres en Rust admite números, alfabetos, Unicode y caracteres especiales. Utilizar elcharpalabra clave para declarar una variable de tipo de datos de caracteres. El tipo char de Rust representa un valor escalar Unicode, lo que significa que puede representar mucho más que solo ASCII. Los valores escalares Unicode van desdeU+0000 a U+D7FF y U+E000 a U+10FFFF inclusivo.

Consideremos un ejemplo para comprender más sobre el tipo de datos 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);
}

La salida del código anterior será:

special character is @
alphabet is A
emoji is