Pular para o conteúdo principal

Funções

Estrutura básica

Funções em Dart são objetos de primeira classe, o que significa que podem ser atribuídas a variáveis, passadas como parâmetros e retornadas de outras funções.

// Função simples
void saudacao() {
print("Olá!");
}

// Função com retorno
int somar(int a, int b) {
return a + b;
}

// Arrow function (função de uma linha)
int multiplicar(int a, int b) => a * b;

// Chamada de funções
saudacao();
int resultado = somar(5, 3); // 8
int produto = multiplicar(4, 2); // 8

Tipos de retorno

// void - não retorna nada
void imprimir(String texto) {
print(texto);
}

// Tipo específico
String obterNome() {
return "João";
}

int calcularIdade(int anoNascimento) {
return DateTime.now().year - anoNascimento;
}

// Retorno nullable
String? buscarNome(int id) {
if (id > 0) {
return "João";
}
return null;
}

Parâmetros

Positional parameters

Parâmetros posicionais são obrigatórios e devem ser passados na ordem:

void apresentar(String nome, int idade) {
print("$nome tem $idade anos");
}

apresentar("João", 25); // OK
// apresentar(25, "João"); // Erro! Ordem errada

Optional positional parameters

Parâmetros opcionais posicionais são envolvidos em colchetes:

void saudar(String nome, [String? sobrenome]) {
if (sobrenome != null) {
print("Olá, $nome $sobrenome");
} else {
print("Olá, $nome");
}
}

saudar("João"); // "Olá, João"
saudar("João", "Silva"); // "Olá, João Silva"

Com valores padrão:

void criarUsuario(String nome, [int idade = 18, bool ativo = true]) {
print("Nome: $nome, Idade: $idade, Ativo: $ativo");
}

criarUsuario("João"); // Nome: João, Idade: 18, Ativo: true
criarUsuario("Maria", 25); // Nome: Maria, Idade: 25, Ativo: true
criarUsuario("Pedro", 30, false); // Nome: Pedro, Idade: 30, Ativo: false

Named parameters

Parâmetros nomeados são opcionais por padrão e identificados por nome:

void criarPerfil(String nome, {int? idade, String? email}) {
print("Nome: $nome");
if (idade != null) print("Idade: $idade");
if (email != null) print("Email: $email");
}

criarPerfil("João");
criarPerfil("Maria", idade: 25);
criarPerfil("Pedro", email: "pedro@email.com", idade: 30);

Com valores padrão:

void configurarApp({String tema = "claro", bool notificacoes = true}) {
print("Tema: $tema, Notificações: $notificacoes");
}

configurarApp(); // Tema: claro, Notificações: true
configurarApp(tema: "escuro"); // Tema: escuro, Notificações: true
configurarApp(notificacoes: false, tema: "escuro");

Parâmetros nomeados obrigatórios (usando required):

void criarPerfil(String nome, {required String email, int? idade}) {
print("Nome: $nome, Email: $email");
if (idade != null) print("Idade: $idade");
}

criarPerfil("João", email: "joao@email.com"); // OK
// criarPerfil("João"); // Erro! email é obrigatório

Funções como objetos de primeira classe

// Atribuir função a variável
var funcao = (int x) => x * 2;
print(funcao(5)); // 10

// Passar função como parâmetro
void processar(List<int> numeros, Function(int) funcao) {
for (var numero in numeros) {
print(funcao(numero));
}
}

processar([1, 2, 3], (x) => x * 2); // 2, 4, 6

// Retornar função
Function criarMultiplicador(int fator) {
return (int x) => x * fator;
}

var multiplicarPor3 = criarMultiplicador(3);
print(multiplicarPor3(5)); // 15

Exercícios

  1. Funções básicas: Crie uma função que calcule o IMC (Índice de Massa Corporal). A fórmula é: peso / (altura × altura). A função deve receber peso e altura como parâmetros e retornar o IMC.

  2. Parâmetros opcionais: Crie uma função saudar que receba um nome obrigatório e opcionalmente um título e um horário. Se o título não for fornecido, use "Sr./Sra.". Se o horário não for fornecido, use "Bom dia".

  3. Parâmetros nomeados: Crie uma função criarUsuario que receba nome (obrigatório), email (obrigatório), idade (opcional) e ativo (opcional, padrão true). Use parâmetros nomeados.

  4. Arrow functions: Crie funções usando arrow functions para: calcular o quadrado de um número, verificar se um número é par, e obter o maior entre dois números.

  5. Funções como objetos: Crie uma função aplicarOperacao que receba uma lista de números e uma função de operação. A função deve aplicar a operação a cada número e retornar uma nova lista com os resultados. Teste com funções que dobram, triplicam e elevam ao quadrado.

Soluções

Ver solução do exercício 1
double calcularIMC(double peso, double altura) {
return peso / (altura * altura);
}

String classificarIMC(double imc) {
if (imc < 18.5) {
return "Abaixo do peso";
} else if (imc < 25) {
return "Peso normal";
} else if (imc < 30) {
return "Sobrepeso";
} else {
return "Obesidade";
}
}

void main() {
double imc = calcularIMC(70.0, 1.75);
print("IMC: ${imc.toStringAsFixed(2)}");
print("Classificação: ${classificarIMC(imc)}");
}
Ver solução do exercício 2
String saudar(String nome, [String? titulo, String? horario]) {
String tituloFinal = titulo ?? "Sr./Sra.";
String horarioFinal = horario ?? "Bom dia";
return "$horarioFinal, $tituloFinal $nome!";
}

void main() {
print(saudar("João")); // Bom dia, Sr./Sra. João!
print(saudar("Maria", "Dr.")); // Bom dia, Dr. Maria!
print(saudar("Pedro", "Prof.", "Boa tarde")); // Boa tarde, Prof. Pedro!

// Com valores padrão
String saudar2(String nome, [String titulo = "Sr./Sra.", String horario = "Bom dia"]) {
return "$horario, $titulo $nome!";
}

print(saudar2("Ana")); // Bom dia, Sr./Sra. Ana!
}
Ver solução do exercício 3
Map<String, dynamic> criarUsuario({
required String nome,
required String email,
int? idade,
bool ativo = true,
}) {
return {
'nome': nome,
'email': email,
'idade': idade,
'ativo': ativo,
};
}

void main() {
var usuario1 = criarUsuario(
nome: "João",
email: "joao@email.com",
);
print(usuario1);

var usuario2 = criarUsuario(
nome: "Maria",
email: "maria@email.com",
idade: 25,
ativo: false,
);
print(usuario2);
}
Ver solução do exercício 4
int quadrado(int n) => n * n;

bool ehPar(int n) => n % 2 == 0;

int maior(int a, int b) => a > b ? a : b;

void main() {
print(quadrado(5)); // 25
print(ehPar(4)); // true
print(ehPar(5)); // false
print(maior(10, 20)); // 20
print(maior(15, 8)); // 15
}
Ver solução do exercício 5
List<int> aplicarOperacao(List<int> numeros, int Function(int) operacao) {
return numeros.map(operacao).toList();
}

void main() {
List<int> numeros = [1, 2, 3, 4, 5];

// Dobrar
var dobrados = aplicarOperacao(numeros, (x) => x * 2);
print(dobrados); // [2, 4, 6, 8, 10]

// Triplicar
var triplicados = aplicarOperacao(numeros, (x) => x * 3);
print(triplicados); // [3, 6, 9, 12, 15]

// Elevar ao quadrado
var quadrados = aplicarOperacao(numeros, (x) => x * x);
print(quadrados); // [1, 4, 9, 16, 25]

// Usando funções nomeadas
int dobrar(int x) => x * 2;
int triplicar(int x) => x * 3;
int quadrado(int x) => x * x;

print(aplicarOperacao(numeros, dobrar));
print(aplicarOperacao(numeros, triplicar));
print(aplicarOperacao(numeros, quadrado));
}