Uma struct, ou estrutura, é um tipo de dados personalizado que nos permite nomear e criar um conjunto de vários valores relacionados que compõem um grupo de dados. Se você estiver familiarizado com uma linguagem orientada a objeto, um struct é como os atributos de dados de um objeto.
Existe três tipos de estruturas que são:
- Estrutura de tuplas que são, basicamente denominadas por tuplas.
- Temos aquela clássica estrutura do C.
- Temos a estrutura de unidade, que são sem campo, são uteis para os genéricos.
struct Tuplestruct(i32, i32);
fn main() {
let number = Tuplestruct(10, 20);
// Destructure
let Tuplestruct(x, y) = number;
println!("x: {}, y: {}", x, y);
}
/*
x: 10, y: 20
*/
Código acima temos uma estrutura com tuplas. Criamos struct na linha 2 informando que terá dois números inteiros, dentro da função main importamos dois números para estrutura após a importação retiramos o mesmo da estrutura e imprimimos abaixo. Nesse exemplo temos uma estrutra de tuplas de uma forma simples.
struct NormalStruct {
a: i32,
b: i32,
}
fn main() {
let ns = NormalStruct { a: 1, b: 2 };
// Destructure
let NormalStruct { a, b } = ns;
println!("a: {}, b: {}", a, b)
}
/*
a: 1, b: 2
*/
Código acima temos uma estrutura comum, criamos uma structs na linha 2 informando que teremos a e b sendo inteiros, dentro da função main importamos números a e b com os números após retiramos os valores da estrutura e imprimimos abaixo.
Mas realmente, como podemos usar isso de forma útil ?
#[derive(Debug)]
struct User {
username: String,
email: String,
active: bool,
}
fn main() {
let user = build_user(
String::from("contato@higordiego.com.br"),
String::from("Higor Diego"),
);
println!("email: {}, active: {}", user.email, user.active);
}
fn build_user(email: String, username: String) -> User {
User {
username: username,
email: email,
active: true,
}
}
/*
email: contato@higordiego.com.br, active: true
*/
Então, vamos pensar da seguinte forma, o código acima tem estrutura para receber usuários, o struct possui atributos de um sistema simples onde temos o nome e email e se o usuário está ativo ou não no sistema. Criamos uma função para gerar esse usuário retornando sua estrutura e após isso na função main imprimimos os valores contidos.
Se parar para pensar um pouco esse struct lembra um modelo ou esquema de um ORM isso é muito familiar para as pessoas que já desenvolvem.
Vamos para um exemplo prático.
Iremos fazer uma chamada nessa API http://ip-api.com/json/187.19.230.194 o retorno dela vem com um JSON da seguinte forma.
{
"as": "AS28126 BRISANET SERVICOS DE TELECOMUNICACOES LTDA",
"city": "Jaguaribe",
"country": "Brazil",
"countryCode": "BR",
"isp": "Brisanet Servicos De Telecomunicacoes Ltda",
"lat": -6.05537,
"lon": -38.506,
"org": "Brisanet Servicos De Telecomunicacoes Ltda",
"query": "187.19.230.194",
"region": "CE",
"regionName": "Ceará",
"status": "success",
"timezone": "America/Fortaleza",
"zip": "63475-000"
}
Iremos criar uma struct que armazena alguns dados desse retorno, segue o exemplo abaixo.
extern crate reqwest;
use serde::{Deserialize};
#[derive(Debug)]
#[derive(Deserialize)]
struct Information {
city: String,
country: String
}
fn main() -> Result<(), Box<std::error::Error>> {
let resp: Information = reqwest::get("http://ip-api.com/json/187.19.230.194")?.json()?;
println!("city: {}", resp.city);
println!("country: {}", resp.country);
Ok(())
}
/*
city: Jaguaribe
country: Brazil
*/
No código acima requisitamos a url usando um pacote chamado request com o método GET informamos que o retorno será em json, após o retorno injetamos os dados no struct e com esse dados pegamos dois atributos daquele json que é o city e country, e por fim imprimimos no console.
O struct é muito útil para estruturar os seus dados, vamos utilizar ele bastante aqui nos próximos posts.
Então galera é isso, espero que tenham gostado até a próxima.