Ferrugem - Estrutura

Matrizes são usadas para representar uma coleção homogênea de valores. Da mesma forma, uma estrutura é outro tipo de dados definido pelo usuário disponível no Rust que nos permite combinar itens de dados de diferentes tipos, incluindo outra estrutura. Uma estrutura define os dados como um par de valores-chave.

Sintaxe - Declarando uma estrutura

A palavra-chave struct é usada para declarar uma estrutura. Uma vez que as estruturas são tipadas estaticamente, cada campo na estrutura deve ser associado a um tipo de dados. As regras e convenções de nomenclatura para uma estrutura são como as de uma variável. O bloco de estrutura deve terminar com um ponto e vírgula.

struct Name_of_structure {
   field1:data_type,
   field2:data_type,
   field3:data_type
}

Sintaxe - Inicializando uma estrutura

Depois de declarar uma estrutura, cada campo deve receber um valor. Isso é conhecido como inicialização.

let instance_name = Name_of_structure {
   field1:value1,
   field2:value2,
   field3:value3
}; 
//NOTE the semicolon
Syntax: Accessing values in a structure
Use the dot notation to access value of a specific field.
instance_name.field1
Illustration
struct Employee {
   name:String,
   company:String,
   age:u32
}
fn main() {
   let emp1 = Employee {
      company:String::from("TutorialsPoint"),
      name:String::from("Mohtashim"),
      age:50
   };
   println!("Name is :{} company is {} age is {}",emp1.name,emp1.company,emp1.age);
}

O exemplo acima declara uma estrutura Employee com três campos - nome, empresa e idade dos tipos. O main () inicializa a estrutura. Ele usa o println! macro para imprimir os valores dos campos definidos na estrutura.

Resultado

Name is :Mohtashim company is TutorialsPoint age is 50

Modificando uma instância de struct

Para modificar uma instância, a variável da instância deve ser marcada como mutável. O exemplo abaixo declara e inicializa uma estrutura chamada Employee e posteriormente modifica o valor do campo age para 40 de 50.

let mut emp1 = Employee {
   company:String::from("TutorialsPoint"),
   name:String::from("Mohtashim"),
   age:50
};
emp1.age = 40;
println!("Name is :{} company is {} age is 
{}",emp1.name,emp1.company,emp1.age);

Resultado

Name is :Mohtashim company is TutorialsPoint age is 40

Passando uma estrutura para uma função

O exemplo a seguir mostra como passar uma instância de struct como um parâmetro. O método de exibição usa uma instância de Employee como parâmetro e imprime os detalhes.

fn display( emp:Employee) {
   println!("Name is :{} company is {} age is 
   {}",emp.name,emp.company,emp.age);
}

Aqui está o programa completo -

//declare a structure
struct Employee {
   name:String,
   company:String,
   age:u32
}
fn main() {
   //initialize a structure
   let emp1 = Employee {
      company:String::from("TutorialsPoint"),
      name:String::from("Mohtashim"),
      age:50
   };
   let emp2 = Employee{
      company:String::from("TutorialsPoint"),
      name:String::from("Kannan"),
      age:32
   };
   //pass emp1 and emp2 to display()
   display(emp1);
   display(emp2);
}
// fetch values of specific structure fields using the 
// operator and print it to the console
fn display( emp:Employee){
   println!("Name is :{} company is {} age is 
   {}",emp.name,emp.company,emp.age);
}

Resultado

Name is :Mohtashim company is TutorialsPoint age is 50
Name is :Kannan company is TutorialsPoint age is 32

Retornando struct de uma função

Vamos considerar uma função who_is_elder () , que compara a idade de dois funcionários e retorna o mais velho.

fn who_is_elder (emp1:Employee,emp2:Employee)->Employee {
   if emp1.age>emp2.age {
      return emp1;
   } else {
      return emp2;
   }
}

Aqui está o programa completo -

fn main() {
   //initialize structure
   let emp1 = Employee{
      company:String::from("TutorialsPoint"),
      name:String::from("Mohtashim"),
      age:50
   };
   let emp2 = Employee {
      company:String::from("TutorialsPoint"),
      name:String::from("Kannan"),
      age:32
   };
   let elder = who_is_elder(emp1,emp2);
   println!("elder is:");

   //prints details of the elder employee
   display(elder);
}
//accepts instances of employee structure and compares their age
fn who_is_elder (emp1:Employee,emp2:Employee)->Employee {
   if emp1.age>emp2.age {
      return emp1;
   } else {
      return emp2;
   }
}
//display name, comapny and age of the employee
fn display( emp:Employee) {
   println!("Name is :{} company is {} age is {}",emp.name,emp.company,emp.age);
}
//declare a structure
struct Employee {
   name:String,
   company:String,
   age:u32
}

Resultado

elder is:
Name is :Mohtashim company is TutorialsPoint age is 50

Método na Estrutura

Métodos são como funções. Eles são um grupo lógico de instruções de programação. Os métodos são declarados com ofnpalavra-chave. O escopo de um método está dentro do bloco de estrutura.

Os métodos são declarados fora do bloco de estrutura. oimplpalavra-chave é usada para definir um método dentro do contexto de uma estrutura. O primeiro parâmetro de um método será sempreself, que representa a instância de chamada da estrutura. Os métodos operam nos membros de dados de uma estrutura.

Para invocar um método, precisamos primeiro instanciar a estrutura. O método pode ser chamado usando a instância da estrutura.

Sintaxe

struct My_struct {}
impl My_struct { 
   //set the method's context
   fn method_name() { 
      //define a method
   }
}

Ilustração

O exemplo a seguir define uma estrutura Rectangle com campos - largura e altura . Uma área de método é definida dentro do contexto da estrutura. O método area acessa os campos da estrutura através da palavra-chave self e calcula a área de um retângulo.

//define dimensions of a rectangle
struct Rectangle {
   width:u32, height:u32
}

//logic to calculate area of a rectangle
impl Rectangle {
   fn area(&self)->u32 {
      //use the . operator to fetch the value of a field via the self keyword
      self.width * self.height
   }
}

fn main() {
   // instanatiate the structure
   let small = Rectangle {
      width:10,
      height:20
   };
   //print the rectangle's area
   println!("width is {} height is {} area of Rectangle 
   is {}",small.width,small.height,small.area());
}

Resultado

width is 10 height is 20 area of Rectangle is 200

Método estático na estrutura

Os métodos estáticos podem ser usados ​​como métodos utilitários. Esses métodos existem mesmo antes de a estrutura ser instanciada. Os métodos estáticos são chamados usando o nome da estrutura e podem ser acessados ​​sem uma instância. Ao contrário dos métodos normais, um método estático não terá o parâmetro & self .

Sintaxe - Declarando um método estático

Um método estático como funções e outros métodos podem conter parâmetros opcionalmente.

impl Structure_Name {
   //static method that creates objects of the Point structure
   fn method_name(param1: datatype, param2: datatype) -> return_type {
      // logic goes here
   }
}

Sintaxe - Invocando um método estático

A structure_name :: syntax é usada para acessar um método estático.

structure_name::method_name(v1,v2)

Ilustração

O exemplo a seguir usa o método getInstance como uma classe de fábrica que cria e retorna instâncias da estrutura Point .

//declare a structure
struct Point {
   x: i32,
   y: i32,
}
impl Point {
   //static method that creates objects of the Point structure
   fn getInstance(x: i32, y: i32) -> Point {
      Point { x: x, y: y }
   }
   //display values of the structure's field
   fn display(&self){
      println!("x ={} y={}",self.x,self.y );
   }
}
fn main(){
   // Invoke the static method
   let p1 = Point::getInstance(10,20);
   p1.display();
}

Resultado

x =10 y=20