No Dart, funções também são objetos — isso diferencia um pouco das outras linguagens de programação.
Funções são objetos de primeira classe
Dart é uma linguagem totalmente orientada a objetos: as próprias funções são objetos, com o tipo Function.
Elas podem ser atribuídas a variáveis e passadas como argumentos para outras funções;
Instâncias de classe podem ser invocadas diretamente como se fossem funções
1 Definição padrão de função
// Declaração completa com anotações de tipo de retorno e parâmetros
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}Code language: JavaScript (javascript)
Exemplo completo
// Tabela de correspondência dos números atômicos dos gases nobres
final Map<int, String> _nobleGases = {
2: 'He',
10: 'Ne',
18: 'Ar',
36: 'Kr',
54: 'Xe',
86: 'Rn',
};
// Declaração completa com tipo de retorno e tipos de parâmetros
// O tipo int não aceita null; use int? para aceitar parâmetros anuláveis
bool isNoble(int? atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void main() {
print(isNoble(null)); // null não é uma chave do mapa → false
print(isNoble(2)); // Corresponde a um gás nobre → true
print(isNoble(9)); // Sem correspondência → false
print(isNoble(86)); // Corresponde a um gás nobre → true
}Code language: PHP (php)
false
true
false
trueCode language: JavaScript (javascript)
2 Omitir anotações de tipo
O guia de estilo Effective Dart recomenda anotações de tipo explícitas e completas para APIs públicas visíveis externamente.
Você pode omitir anotações de tipo em funções privadas internas
Exemplo
final Map<int, String> _nobleGases = {
2: 'He',
10: 'Ne',
18: 'Ar',
36: 'Kr',
54: 'Xe',
86: 'Rn',
};
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void main() {
print(isNoble(null)); // null não é uma chave do mapa → false
print(isNoble(2)); // Corresponde a um gás nobre → true
print(isNoble(9)); // Sem correspondência → false
print(isNoble(86)); // Corresponde a um gás nobre → true
}
Code language: PHP (php)
No exemplo acima, a função isNoble omite o tipo de retorno bool e o tipo de parâmetro int?, mas funciona normalmente.
Quando você não escreve tipos, Dart realiza uma inferência de tipo automática:
- Parâmetro
atomicNumber: Sem tipo explícito → inferido comodynamic(tipo dinâmico, aceita qualquer valor: números, strings, null) - Valor de retorno: Sem anotação de tipo no início → Dart deduz que o tipo de retorno é
boola partir da expressão apósreturn, sem escrevê-lo no código
Por que APIs públicas devem obrigatoriamente ter tipos explícitos?
Legibilidade: Desenvolvedores que chamam sua função veem imediatamente os tipos de entrada e saída, sem precisar ler o código interno para adivinhar;
Segurança de tipos: O tipo dynamic desativa a verificação estática; passar tipos incorretos não gera erros de compilação e frequentemente causa falhas em tempo de execução;
Intellisense da IDE: Anotações de tipo ativam autocompletar e dicas de parâmetros no editor; sem tipos, a IDE não consegue mostrar sugestões precisas.
Quando posso omitir anotações de tipo?
Apenas recomendado para código privado local — funções usadas exclusivamente dentro do arquivo atual e nunca invocadas externamente.
Sintaxe curta de seta (=>)
Se o corpo da função (código dentro de {}) conter apenas uma única expressão de retorno, você pode usar a sintaxe de seta.
Exemplo
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;Code language: PHP (php)
=> exprequivale a{ return expr; };- Apenas expressões podem ser escritas entre a seta e o ponto e vírgula; instruções como
ifsão proibidas (use operadores ternários no lugar).
// Tabela de correspondência dos números atômicos dos gases nobres
final Map<int, String> _nobleGases = {
2: 'Hélio',
10: 'Neônio',
18: 'Argônio',
36: 'Criptônio',
54: 'Xenônio',
86: 'Rádon',
};
// Função curta de seta: retorna diretamente uma expressão em uma linha, equivalente a funções de bloco com return
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
void main() {
// Testar gases nobres existentes
print(isNoble(2)); // true
print(isNoble(18)); // true
// Testar elementos comuns
print(isNoble(6)); // false (Carbono)
print(isNoble(99)); // false (nenhum elemento correspondente)
}Code language: PHP (php)

Parâmetros
Funções suportam parâmetros posicionais obrigatórios, seguidos de apenas uma das duas opções: parâmetros nomeados ou parâmetros posicionais opcionais — não podem ser misturados.
Vírgulas finais , são permitidas ao definir ou chamar parâmetros para melhorar a legibilidade do código.
1. Parâmetros nomeados Named parameters
Delimitados por {}, opcionais por padrão; adicione required para forçar a passagem obrigatória.
1) Parâmetros nomeados anuláveis básicos (sem valor padrão, o valor padrão é null, o tipo deve ser marcado com ? para ser anulável)
void enableFlags({bool? bold, bool? hidden}) {}
// Especificar explicitamente os nomes dos parâmetros na chamada
enableFlags(bold: true, hidden: false);
Code language: JavaScript (javascript)
Exemplo completo
/// Ativar flags de estilo de texto: negrito, oculto
void enableFlags({bool? bold, bool? hidden}) {
print('Negrito: $bold, Oculto: $hidden');
}
void main() {
// Passar todos os parâmetros nomeados
enableFlags(bold: true, hidden: false);
// Passar apenas um parâmetro nomeado, o outro fica null
enableFlags(bold: true);
// Passar apenas hidden
enableFlags(hidden: true);
// Não passar nenhum parâmetro, ambos os valores são null
enableFlags();
}Code language: JavaScript (javascript)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Negrito: true, Oculto: false
Negrito: true, Oculto: null
Negrito: null, Oculto: true
Negrito: null, Oculto: nullCode language: JavaScript (javascript)
2) Definir valores padrão constantes em tempo de compilação (não precisa da marca de nulabilidade pois existe um valor padrão)
void enableFlags({bool bold = false, bool hidden = false}) {}
enableFlags(bold: true); // hidden usa automaticamente false
Code language: JavaScript (javascript)
Exemplo
/// Ativar flags de estilo de texto: negrito, oculto
void enableFlags({bool bold = false, bool hidden = false}) {
print('Negrito: $bold, Oculto: $hidden');
}
void main() {
enableFlags();//Sem parâmetros passados, ambos usam o valor padrão false → Negrito: false, Oculto: false
}Code language: JavaScript (javascript)
3) Parâmetros nomeados obrigatórios com required (Observação: Muito usado em construtores de componentes Flutter). O exemplo abaixo é código Flutter; saiba mais nos tutoriais de Flutter.
const Scrollbar({super.key, required Widget child});
// Parâmetros required também aceitam tipos anuláveis
const Scrollbar({super.key, required Widget? child});
Code language: JavaScript (javascript)
Dart não obriga a colocar parâmetros nomeados no final da lista; eles podem ser inseridos em qualquer posição da lista de parâmetros
repeat(times: 2, () {})Code language: CSS (css)
2. Parâmetros posicionais opcionais Optional positional parameters
Delimitados por [], valem null se omitidos; valores padrão constantes podem ser definidos.
// Sem valor padrão, tipo marcado com ?
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) result = '$result with a $device';
return result;
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
assert(say('Bob', 'Howdy', 'smoke signal') == 'Bob says Howdy with a smoke signal');
Code language: PHP (php)
Exemplo completo
// [String? device] parâmetro posicional opcional sem valor padrão, vale null se omitido
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device'; //Adicionar informações do dispositivo à frase se device não for null
}
return result;
}
void main() {
// Omitir o terceiro parâmetro opcional
String res1 = say('Bob', 'Howdy');
print(res1);
// Passar o terceiro parâmetro posicional opcional
String res2 = say('Bob', 'Howdy', 'smoke signal');
print(res2);
// Passar manualmente null para o parâmetro opcional
String res3 = say('Alice', 'Hi', null);
print(res3);
}Code language: JavaScript (javascript)
Definir valores padrão:
String say(String from, String msg, [String device = 'carrier pigeon']) {
return '$from says $msg with a $device';
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');
Code language: PHP (php)
Exemplo completo
// Parâmetro posicional opcional com valor padrão carrier pigeon (pombo mensageiro)
String say(String from, String msg, [String device = 'carrier pigeon']) {
return '$from says $msg with a $device';
}
void main() {
// Omitir o terceiro parâmetro opcional, usa automaticamente o valor padrão carrier pigeon
String res1 = say('Bob', 'Howdy');
print(res1); //Bob says Howdy with a carrier pigeon
// Passar dispositivo personalizado para sobrescrever o valor padrão
String res2 = say('Bob', 'Howdy', 'smoke signal');
print(res2); //Bob says Howdy with a smoke signal
String res3 = say('Alice', 'Hello', 'mobile phone');
print(res3); // Alice says Hello with a mobile phone
String res4 = say('Jack', 'Tom', 'website foxdevelop.com');
print(res4); // Jack says Tom with a website foxdevelop.com
}Code language: JavaScript (javascript)
Resultado da execução
Built firstdart:firstdart.
Bob says Howdy with a carrier pigeon
Bob says Howdy with a smoke signal
Alice says Hello with a mobile phone
Jack says Tom with a website foxdevelop.comCode language: JavaScript (javascript)
Função de ponto de entrada main ()
Todo programa Dart precisa de uma função main() de nível superior; ela é o único ponto de entrada de execução do programa.
- Versão básica sem parâmetros
void main() {
print('Hello, welcome to foxdevelop.com!');
}
Code language: JavaScript (javascript)
Hello, welcome to foxdevelop.com!Code language: CSS (css)
- Programa de linha de comando recebendo argumentos de inicialização
// Comando de execução: dart run firstdart.dart 1 test
void main(List<String> arguments) {
print(arguments); // [1, test]
}
Code language: JavaScript (javascript)
Use a biblioteca oficial args para análise complexa de argumentos de linha de comando.
Substitua firstdart.dart acima pelo nome do seu arquivo Dart

Funções como objetos de primeira classe First-class objects
1. Passar funções como parâmetros
void printElement(int element) => print(element);
var list = [1, 2, 3];
list.forEach(printElement); // Passar a função diretamente
Code language: PHP (php)
Exemplo completo
void main() {
void printElement(int element) => print(element);
var list = [1, 2, 3];
list.forEach(printElement); // Passar a função diretamente
}Code language: PHP (php)
Saída
1
2
3
2. Atribuir funções anônimas a variáveis
void main() {
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
print(loudify('hello')); //!!! HELLO !!!
}Code language: JavaScript (javascript)
Tipos de função Function Type
Você pode declarar explicitamente os tipos de variáveis de função
Formato: TipoRetorno Function(ListaParametros, {ParametrosNomeados})
void greet(String name, {String greeting = 'Hello'}) => print('$greeting $name!');
// Declarar variável de tipo função
void Function(String, {String greeting}) g = greet;
g('Dash', greeting: 'Howdy');
Code language: JavaScript (javascript)
Use typedef para criar aliases de tipos de função, melhorar a reutilização e legibilidade.
{String greeting}) → Um parâmetro nomeado greeting do tipo String
void main() {
void greet(String name, {String greeting = 'Hello'}) => print('$greeting $name!');
// Declarar variável de tipo função
void Function(String, {String greeting}) g = greet;
g('Jack', greeting: 'Howdy');
}Code language: JavaScript (javascript)
Saída
Howdy Jack!
Funções anônimas (Lambda / Closure fechamento léxico)
Funções sem nome definido, duas formas de escrita:
- Sintaxe de bloco (várias linhas)
void main() {
const list = ['apples', 'bananas'];
var uppercaseList = list.map((item) {
return item.toUpperCase();
}).toList();
print(uppercaseList);
}Code language: PHP (php)
(item) { return item.toUpperCase(); } no código anterior é uma função anônima (lambda)
Saída: [APPLES, BANANAS]
- Abreviatura de seta (expressão de uma única linha)
void main() {
const list = ['fox', 'develop','foxdevelop.com'];
var uppercaseList = list.map((item) => item.toUpperCase()).toList();
uppercaseList.forEach((item) => print('$item: ${item.length}'));
}
Code language: PHP (php)
Saída
FOX: 3
DEVELOP: 7
FOXDEVELOP.COM: 14Code language: HTTP (http)
Escopo léxico Lexical scope
Dart usa um escopo léxico estático: o escopo de uma variável é definido pela hierarquia de chaves do código, e os escopos internos podem acessar todas as variáveis dos escopos externos.
bool topLevel = true;
void main() {
var insideMain = true;
void myFunction() {
var insideFunction = true;
void nestedFunction() {
var insideNestedFunction = true;
// Todos acessíveis
assert(topLevel && insideMain && insideFunction && insideNestedFunction);
}
}
}
Code language: JavaScript (javascript)
Fechamentos léxicos Lexical closures
Fechamento: um objeto função pode capturar e conservar variáveis do escopo externo, e acessá-las mesmo depois de sair do escopo original.
Function makeAdder(int addBy) {
// Capturar variável externa addBy
return (int i) => addBy + i;
}
void main() {
var add2 = makeAdder(2);
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
Code language: PHP (php)
Desglose passo a passo do fluxo de execução anterior
Passo 1: var add2 = makeAdder(2);
- Executar
makeAdder, passaraddBy = 2 - Criar função anônima:
(int i) => 2 + i - Atribuir essa função à variável
add2. Nesse momento add2 é um objeto função cujo corpo é(int i) => 2 + i; recebe um inteiro i e retorna i+2 - A execução da função
makeAdderfinaliza, mas a função anônima lembra permanentementeaddBy=2
Passo 2: var add4 = makeAdder(4);
- Executar
makeAddernovamente, passaraddBy = 4 - Criar uma nova função anônima totalmente independente:
(int i) => 4 + i - Atribuir a
add4, que armazena sua própria cópia independente deaddBy=4sem interferir com add2. Ou seja, o valor addBy é guardado separadamente nos dois objetos função add2 e add4, um guarda 2 e o outro 4
- A chamada a
makeAdder(2)gera um fechamento independente com um valor vinculado únicoaddBy = 2, atribuído aadd2; - A chamada a
makeAdder(4)gera um fechamento totalmente novo e separado com um valor vinculado únicoaddBy = 4, atribuído aadd4; add2eadd4são objetos função completamente separados, cada um armazena em privado sua variáveladdBycapturada sem interferir mutuamente.
Passo 3: Invocar add2(3)
Executar função interna: 2 + 3 = 5, a asserção se cumpre
Passo 4: Invocar add4(3)
Executar função interna: 4 + 3 = 7, a asserção se cumpre
Tear-offs de função
Se invocar uma função/método sem parênteses, cria-se um tear-off (fechamento leve), que substitui as lambdas anônimas escritas manualmente para um código mais limpo.
Esta é a sintaxe recomendada; basta passar a função diretamente.
var charCodes = [68, 97, 114, 116];
var buffer = StringBuffer();
charCodes.forEach(print); // Tear-off de função
charCodes.forEach(buffer.write); // Tear-off de método
Code language: PHP (php)
Sintaxe equivalente mais longa
charCodes.forEach((code) => print(code));
charCodes.forEach((code) => buffer.write(code));
Code language: PHP (php)
Verificação de igualdade de funções
- Funções de nível superior, métodos estáticos:
==retorna true se os nomes de função coincidirem exatamente; - Métodos de instância: apenas os tear-offs vinculados à mesma instância de objeto são considerados iguais.
void foo() {}
class A {
static void bar() {}
void baz() {}
}
void main() {
var x = foo;
assert(foo == x);
x = A.bar;
assert(A.bar == x);
var v = A(), w = A(), y = w;
x = w.baz;
assert(y.baz == x); // Mesma instância → iguais
assert(v.baz != w.baz); // Instâncias diferentes → não iguais
}
Code language: JavaScript (javascript)
Valores de retorno Return values
- Todas as funções têm valor de retorno: se não houver um
returnexplícito, é adicionado implicitamentereturn null;no final
foo() {}
assert(foo() == null);
Code language: JavaScript (javascript)
- Retornar vários valores: usar tuplas Record
(String, int) foo() {
return ('something', 42);
}
Code language: JavaScript (javascript)
Acessores Getter & Setter
Ler ou atribuir qualquer propriedade equivale fundamentalmente a chamar seu getter ou setter; as variáveis normais geram automaticamente acessores implícitos, também é possível defini-los explicitamente à mão.
Vantagem: o código externo acessa uniformemente com .nomePropriedade, a lógica interna pode ser modificada em qualquer momento sem atualizar o código chamante externo.
String _secret = 'Hello';
// Getter para leitura
String get secret {
print('Getter invocado');
return _secret.toUpperCase();
}
// Setter para atribuições
set secret(String newMsg) {
print('Setter invocado');
if (newMsg.isNotEmpty) _secret = newMsg;
}
void main() {
print(secret); // Leitura, ativa getter → HELLO
secret = 'Dart is fun'; // Atribuição, ativa setter
print(secret); // DART IS FUN
}
Code language: JavaScript (javascript)
* Geradores Generators
Geram sequências de forma diferida sob demanda, duas variantes: síncrono e assíncrono, usam yield para emitir valores.
- Gerador síncrono
sync*, retornaIterable
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
Code language: HTML, XML (xml)
- Gerador assíncrono
async*, retornaStream
Stream<int> asyncNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
Code language: JavaScript (javascript)
- Otimização de geradores recursivos
yield*(delega a outro gerador para melhorar o desempenho)
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
Code language: HTML, XML (xml)