Ferrugem - Enums

Na programação Rust, quando temos que selecionar um valor de uma lista de variantes possíveis, usamos tipos de dados de enumeração. Um tipo enumerado é declarado usando a palavra-chave enum . A seguir está a sintaxe de enum -

enum enum_name {
   variant1,
   variant2,
   variant3
}

Ilustração: Usando uma Enumeração

O exemplo declara um enum - GenderCategory , que possui variantes como Masculino e Feminino. A impressão! macro exibe o valor do enum. O compilador lançará um erro, o trait std :: fmt :: Debug não está implementado para GenderCategory . O atributo # [derive (Debug)] é usado para suprimir esse erro.

// The `derive` attribute automatically creates the implementation
// required to make this `enum` printable with `fmt::Debug`.
#[derive(Debug)]
enum GenderCategory {
   Male,Female
}
fn main() {
   let male = GenderCategory::Male;
   let female = GenderCategory::Female;

   println!("{:?}",male);
   println!("{:?}",female);
}

Resultado

Male
Female

Struct e Enum

O exemplo a seguir define uma estrutura Person. O campo gênero é do tipo GenderCategory (que é um enum) e pode ser atribuído a Masculino ou Feminino como valor.

// The `derive` attribute automatically creates the 
implementation
// required to make this `enum` printable with 
`fmt::Debug`.

#[derive(Debug)]
enum GenderCategory {
   Male,Female
}

// The `derive` attribute automatically creates the implementation
// required to make this `struct` printable with `fmt::Debug`.
#[derive(Debug)]
struct Person {
   name:String,
   gender:GenderCategory
}

fn main() {
   let p1 = Person {
      name:String::from("Mohtashim"),
      gender:GenderCategory::Male
   };
   let p2 = Person {
      name:String::from("Amy"),
      gender:GenderCategory::Female
   };
   println!("{:?}",p1);
   println!("{:?}",p2);
}

O exemplo cria os objetos p1 e p2 do tipo Person e inicializa os atributos, nome e gênero de cada um desses objetos.

Resultado

Person { name: "Mohtashim", gender: Male }
Person { name: "Amy", gender: Female }

Opção Enum

Option é um enum predefinido na biblioteca padrão do Rust. Este enum tem dois valores - Alguns (dados) e Nenhum.

Sintaxe

enum Option<T> {
   Some(T),      //used to return a value
   None          // used to return null, as Rust doesn't support 
   the null keyword
}

Aqui, o tipo T representa o valor de qualquer tipo.

Rust não oferece suporte à palavra-chave null . O valor None , em enumOption , pode ser usado por uma função para retornar um valor nulo. Se houver dados para retornar, a função pode retornar Alguns (dados) .

Vamos entender isso com um exemplo -

O programa define uma função is_even () , com um tipo de retorno Option. A função verifica se o valor passado é um número par. Se a entrada for par, um valor verdadeiro será retornado, caso contrário, a função retornará Nenhum .

fn main() {
   let result = is_even(3);
   println!("{:?}",result);
   println!("{:?}",is_even(30));
}
fn is_even(no:i32)->Option<bool> {
   if no%2 == 0 {
      Some(true)
   } else {
      None
   }
}

Resultado

None
Some(true)

Declaração de correspondência e enum

A declaração de correspondência pode ser usada para comparar valores armazenados em um enum. O exemplo a seguir define uma função, print_size , que leva CarType enum como parâmetro. A função compara os valores dos parâmetros com um conjunto predefinido de constantes e exibe a mensagem apropriada.

enum CarType {
   Hatch,
   Sedan,
   SUV
}
fn print_size(car:CarType) {
   match car {
      CarType::Hatch => {
         println!("Small sized car");
      },
      CarType::Sedan => {
         println!("medium sized car");
      },
      CarType::SUV =>{
         println!("Large sized Sports Utility car");
      }
   }
}
fn main(){
   print_size(CarType::SUV);
   print_size(CarType::Hatch);
   print_size(CarType::Sedan);
}

Resultado

Large sized Sports Utility car
Small sized car
medium sized car

Combinar com Opção

O exemplo da função is_even , que retorna o tipo de opção, também pode ser implementado com a declaração de correspondência, conforme mostrado abaixo -

fn main() {
   match is_even(5) {
      Some(data) => {
         if data==true {
            println!("Even no");
         }
      },
      None => {
         println!("not even");
      }
   }
}
fn is_even(no:i32)->Option<bool> {
   if no%2 == 0 {
      Some(true)
   } else {
      None
   }
}

Resultado

not even

Corresponder e Enum com o tipo de dados

É possível adicionar o tipo de dados a cada variante de um enum. No exemplo a seguir, as variantes Name e Usr_ID do enum são dos tipos String e integer, respectivamente. O exemplo a seguir mostra o uso da instrução match com um enum com um tipo de dados.

// The `derive` attribute automatically creates the implementation
// required to make this `enum` printable with `fmt::Debug`.
#[derive(Debug)]
enum GenderCategory {
   Name(String),Usr_ID(i32)
}
fn main() {
   let p1 = GenderCategory::Name(String::from("Mohtashim"));
   let p2 = GenderCategory::Usr_ID(100);
   println!("{:?}",p1);
   println!("{:?}",p2);

   match p1 {
      GenderCategory::Name(val)=> {
         println!("{}",val);
      }
      GenderCategory::Usr_ID(val)=> {
         println!("{}",val);
      }
   }
}

Resultado

Name("Mohtashim")
Usr_ID(100)
Mohtashim