• Home

    Escolha seu Plano

    Carreiras Alura

    Evolua com profundidade técnica, direção clara e aplicação prática.

    Jornadas guiadas do básico ao avançado com checkpoints práticos, desenhadas para quem busca profundidade e protagonismo técnico.

    Iniciante

    Comece do zero com uma trilha clara e progressiva.

    Fundamentos práticos para dar os primeiros passos com segurança e construir uma base sólida.

    Intermediário

    Continue sua evolução com cursos que conectam fundamentos, ferramentas e prática profissional. Ganhe autonomia, e avance para projetos mais completos.

    Avançado

    Aprofunde temas técnicos e estratégicos para enfrentar desafios mais complexos. Explore boas práticas, arquitetura, performance com visão profissional.

    Cursos

    Ver mais cursos de Back-end
    • Pensamento computacional: fundamentos da computação e lógica de programação
    • Lógica de programação: mergulhe em programação com JavaScript
    • DDD: fundamentos do design orientado a domínio
    • ASP.NET: autenticação e autorização em APIs e aplicações web
    • Microsserviços: migração de monólitos e modularização

    Cursos

    Ver mais cursos de Dados
    • Python para Dados: primeiros passos
    • Excel: domine o editor de planilhas
    • Engenharia de Dados: Orquestração de Pipelines com Apache Airflow
    • Power BI Desktop: construindo meu primeiro dashboard
    • Governança e Arquitetura de Dados

    Cursos

    Ver mais cursos de Inteligência Artificial
    • IA: Explorando o Potencial da Inteligência Artificial Generativa
    • Engenharia de Prompt: Criando Prompts Eficazes para IA Generativa
    • Claude para Análise de Dados: prompts, integrações e automações
    • Agno: criando agentes e sistemas multiagente
    • Engenharia de software na era da IA: segurança de aplicações com agentes, MCPs e código gerado por IA

    Cursos

    Ver mais cursos de Front-end
    • HTML e CSS: ambiente, estrutura e estilo
    • React: realizando testes avançados com Jest e Testing Library
    • React: integrando TypeScript em projetos
    • JavaScript: aprendendo a programar
    • React: aplicando arquiteturas de Micro frontends

    Cursos

    Ver mais cursos de DevOps
    • Sistema Operacional Linux: fundamentos e administração prática
    • Containers e Docker: empacotamento, isolamento e gestão
    • Redes: dos conceitos iniciais à criação de uma intranet
    • Linux: gerenciando diretórios, arquivos, permissões e processos
    • Cibersegurança: Fundamentos e práticas integradas

    Cursos

    Ver mais cursos de UX & Design
    • UX Research: mapeando a experiência da pessoa usuária
    • UX/UI Design: Entregando produtos digitais com IA
    • UI Design: Prototipação e animações interativas
    • Figma: Conhecendo o programa
    • Product Design: métricas e ciclo de vida do produto

    Cursos

    Ver mais cursos de Gestão & Negócios
    • Canva: Criação de landing pages e e-mail marketing
    • Agilidade: como ela pode ajudar a criar um time de alta performance
    • Google Analytics 4: Extrair insights e configurar eventos
    • Management 3.0: gerencie o ambiente, não as pessoas
    • Automação de processos com n8n: Inteligência de dados para Marketing

    Cursos

    Ver mais cursos de Mobile
    • React Native: Estilização e Layouts com Flexbox e StyleSheet
    • Flutter: Graphql e suporte offline
    • Android com Gemini: Trabalhando com textos e imagens na IA
    • Dart: trabalhando com orientação a objetos
    • React Native: Dominando Listas com FlatList e ScrollView

    Carreiras

    Ver mais carreiras
    • Especialista em IA
    • Engenharia de IA
    • Ai native software engineering
    • Arquitetura de Soluções com IA
    • AI Product Design
    • Engenharia de Machine Learning
    • Desenvolvimento Front-End React
    • Engenharia de Dados
    • Cloud Security
    • Social Media Marketing
    • Engenharia de Agentes de IA

    Cursos

    • Engenharia de Prompt: Prompts Eficazes para IA Generativa
    • Claude Code: Criando sua Primeira Aplicação
    • Python: Crie sua Primeira Aplicação
    • Git e GitHub: Compartilhando e Colaborando
    • N8N: Fluxos de Trabalho Avançados

    Cursos

    • Copilot Studio: Solução Multiagentes
    • Padrões de API HTTP e Modelagem de APIs
    • Python para Análise de Dados com SQL
    • Docker: Criando e Gerenciando Containers
    • Design com IA: Otimizando o Processo Criativo

    Cursos

    • Model Context Protocol (MCP)
    • Spec-Driven Development: Dev Assistido por Agentes
    • Arquitetura de Sistemas Distribuídos com Java
    • Governança de Modelos e Reprodutibilidade
    • Pentest: Vulnerabilidades em Aplicações Web

    Escolha seu Plano

    Skills & Go

    O Skills & Go é para Tech Leads, Product Managers, estrategistas e early adopters que transformam ideias em soluções de alto impacto. Em cursos ao vivo e 100% online, você domina a nova era da IA em tempo real.

    Aulas ao vivo

    Saiba mais
    • Agentic Engineering: orquestre múltiplos agentes com confiabilidade
    • Building AI Products: transforme ideias em produtos reais com IA
    • AI Data Strategy: transforme dados em decisões estratégicas com IA

    Escolha seu Plano

    Eventos Alura

    Nossos eventos são pensados para quem quer estar à frente das mudanças em tecnologia, IA e inovação. Em experiências presenciais, você acompanha tendências e se conecta com especialistas que estão moldando o futuro.

    Próximos eventos

    • Imersão Engenharia de Software: Dev na Era da IA
    • IA Conference
    • Alura Signals
  • Talent Lab
  • IA

    Escolha seu Plano

    Conteúdos gratuitos

    Explore conteúdos gratuitos para aprender tecnologia no seu ritmo. Encontre artigos com conteúdos técnicos para aprender na prática, notícias para acompanhar as principais tendências do mercado e o Alura Labs, com análises e reflexões de especialistas sobre tecnologia, IA e carreira.

    Conteúdos gratuitos

    • Artigos
    • Notícias
    • Alura Labs
  • Para Empresas
Ver planos
Links principais
  • Planos e Promoções
  • Links complementares do menu mobile
  • Talent lab
  • Inteligência Artificial
  • Pós Graduações
  • Para Empresas
  • Sobre a Alura
  • Grupo Alun
  • Entrar
    • Home
    • Carreiras
    • Skills & Go
    • Talent Lab
    • Inteligência Artificial
    • Pós Graduações
    • Artigos
    • Sobre a Alura
    • Grupo Alun
    LoginContato
    • LinkedIn
    • Instagram
    • YouTube
    1. Página inicial
    2. Mobile
    3. Dart: O que é? Como começar a estudar? Para quê serve?

    Dart: O que é? Como começar a estudar? Para quê serve?

    31 min31 minutos de leitura

    31 min31 minutos de leitura

    Publicado: 06/06/2024

    1. O que é Dart?
    2. A sintaxe do Dart
    3. Como instalar o Dart
    4. Como iniciar um projeto Dart
    5. Tipos de dados
    6. Funções
    7. Laços de repetição
    8. Do While
    9. Classes
    10. Dart e o Null safety
    11. Alterando propriedades
    12. Valores constantes
    13. Propriedades privadas
    14. Métodos de uma classe
    15. Instalando pacotes
    16. Desvantagens do Dart
    17. Como aprender Dart
    18. Conclusão

    Se você está atento às novidades do desenvolvimento de aplicativos, provavelmente já ouviu falar de Dart, especialmente em conjunto com o famoso Flutter.

    Imagine criar aplicativos que funcionam em Android, iOS e Web, tudo a partir de um único código-base. Parece mágico, não é?

    Bem, essa mágica tem um nome: Flutter, e no coração dessa tecnologia está o Dart.

    Mas não se engane, Dart não é apenas um coadjuvante. Ele é a estrela que compila seu código para rodar em diversas plataformas.

    Então, o que exatamente é Dart e por que ele é tão crucial? Vamos descobrir!

    O que é Dart?

    Dart é uma linguagem de programação desenvolvida pela Google, semelhante a Java, C++, e JavaScript.

    Ela é "levemente tipada" e pode ser tanto interpretada quanto compilada. Dart foi criada com o objetivo de ser uma linguagem multiplataforma, permitindo que você escreva o código uma vez e o execute em diversas plataformas.

    Recentemente, Dart tem sido amplamente utilizada no Flutter, como servidor web e, principalmente, para criar ferramentas para a própria linguagem, como o compilador e o analisador de código, todos escritos em Dart.

    Dart foi projetada para ser fácil de aprender. Sua familiaridade com outras linguagens populares do mercado reduz a necessidade de aprender novas estruturas e sintaxes.

    Além disso, é fácil iniciar com Dart, pois é possível testar a linguagem diretamente no navegador.

    Essas são as declarações da Google. Agora, vou compartilhar minhas motivações:

    • Realmente é mais fácil começar a aprender se você já tem conhecimento em alguma outra linguagem de programação, principalmente alguma linguagem que siga bastante o paradigma de Orientação à Objetos;
    • A documentação é bem extensa, bem escrita e com várias ferramentas de busca;
    • A instalação é bem simples, podendo apenas baixar um arquivo .zip e depois adicionar uma variável de ambiente;
    • Não precisa de uma IDE específica para codar e aproveitar as funcionalidades (como o hot reload);
    • Você pode utilizar ItelliJ, AndroiStudio, xcode, Visual Studio Code e até mesmo NeoVim!;
    • Tem uma comunidade ativa e que produz diversas bibliotecas e extensões;
    • Tudo que a comunidade produz vai para um repositório chamado pub.dev.

    E acho que o mais importante: é um código aberto (open source)! Bacana, né?!

    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    A sintaxe do Dart

    Vamos ver um exemplo de código Dart:

    void main() {
      print('Hello World');
    }
    

    O código acima imprime no console a frase: "Hello World". Por ora é um código simples, mas é uma forma de mostrar como é fácil começar com Dart.

    Vamos aprofundar um pouco mais, escrevendo uma função:

    void main() {
      void sumNumbers() {
        print(10 + 10);
      }
      sumNumbers();
    }
    

    O código acima imprime no console o número 20. Também é um código simples, mas vemos algumas funcionalidades extras da linguagem.

    Por exemplo: se você veio de outras linguagens, deu para perceber que para executar um código Dart, é necessário ter a função main().

    Outro detalhe é na palavra void. Isso quer dizer que é importante dizer o tipo de retorno (se existir) de uma função.

    Por fim, notamos também que a linguagem requer o uso de ; no final de cada linha executada.

    Vamos ver um último exemplo:

    void main() {
    	var texto = "Um texto qualquer";
    	String outroTexto = "que complementa outro texto.";
    	minhaFuncao() {
    		return texto + " " + outroTexto;
    	}
    	minhaFuncao();
    }
    

    Rodando o código acima, devemos ter o seguinte resultado no console:

    Um texto qualquer que complementa outro texto.
    

    Dart é uma linguagem "levemente tipada", o que significa que, similar ao JavaScript, permite declarar variáveis sem especificar o tipo de dado.

    Também é possível omitir o tipo de retorno das funções. No entanto, uma diferença crucial é que, se o código tentar realizar uma operação com uma String em Dart, o programa lança uma exceção, enquanto no JavaScript, embora o comportamento seja incorreto, o programa continua funcionando.

    Portanto, apesar de permitir omissões para facilitar a escrita de código, Dart é, na verdade, uma linguagem fortemente tipada.

    Como instalar o Dart

    Não vou passar um tutorial passo a passo de como instalar o Dart, até porque varia bastante de sistema operacional para sistema operacional, mas vou deixar aqui a documentação oficial para que você possa acompanhar o processo.

    Confira o link do processo de instalação.

    Como iniciar um projeto Dart

    Depois de instalado, nós podemos iniciar um projeto Dart de várias maneiras. O que eu mais recomendo sempre fazer é utilizar comandos no terminal.

    É uma garantia de que o processo será igual independente da IDE que você esteja utilizando.

    Outro detalhe é que, para este exemplo, utilizarei o Visual Studio Code com os seguintes plugins e versões:

    • Visual Studio Code na versão 1.89.1;
    • Plugin Dart na versão 3.88.1 (dartcode.org).

    Atenção! Eu já estou assumindo que você conhece comandos básicos do terminal, como ls, cd, mkdir e também como funciona a estrutura básica de arquivos no seu computador (como identificar a pasta que você está e a árvore de arquivos).

    No meu terminal, vou navegar para a minha pasta de documentos, onde tenho uma outra pasta de estudos. Dentro dela vou rodar o seguinte comando no terminal:

    dart create meu_app
    

    Bom, dentro do meu terminal apareceu a seguinte mensagem:

    ❯ dart create meu_app
    Creating meu_app using template console...
      .gitignore
      analysis_options.yaml
      CHANGELOG.md
      pubspec.yaml
      README.md
      bin/meu_app.dart
      lib/meu_app.dart
      test/meu_app_test.dart
    Running pub get...                     1.7s
      Resolving dependencies...
      Changed 48 dependencies!
      3 packages have newer versions incompatible with dependency constraints.
      Try `dart pub outdated` for more information.
    Created project meu_app in meu_app! In order to get started, run the following commands:
      cd meu_app
      dart run
    

    Observe que esse comando gerou várias pastas e arquivos para nós. Agora podemos ir no Visual Studio Code.

    Abra o seu VSCode e em seguida abra a pasta meu_app que nós criamos através do comando dart create.

    Você deve ter uma estrutura de arquivos parecida com esta:

    A imagem exibe uma captura de tela de um editor de código com um painel de explorador de arquivos à esquerda. O explorador de arquivos mostra uma lista de arquivos e pastas, indicando que provavelmente faz parte de um ambiente de desenvolvimento de software. O projeto destacado tem o nome “MEU_APP”, sugerindo que o usuário pode estar trabalhando em um aplicativo ou projeto com esse nome. Dentro do diretório “MEU_APP”, há várias outras pastas e arquivos visíveis: “bin”, “lib”, “test”, “.dart_tool”, “.idea”, “.gitignore”, “analysis_options.yaml”, “CHANGELOG.md”, “pubspec.lock”, “pubspec.yaml” e “README.md”. Esses itens sugerem que este é provavelmente um projeto na linguagem de programação Dart, conforme indicado pela presença de arquivos específicos do Dart, como “.dart_tool”, e pelo uso de arquivos “.yaml”, que são frequentemente usados para configuração em projetos Dart. Além disso, há um ícone semelhante a um frasco de laboratório ao lado da pasta chamada ‘test’, o que geralmente denota scripts ou estruturas de teste em projetos de desenvolvimento.

    - .dart_tool
    - bin
    - lib
    - test
    .gitignore
    analysis_opgions.yaml
    CHANGELOG.md
    pubspec.lock
    pubspec.yaml
    README.md
    

    Podemos fechar nosso terminal e agora vamos entender um pouco de como funciona a estrutura de arquivos do Dart.

    Vamos ignorar a pasta .dart_tool e vamos direto para a pasta bin. Dentro da pasta bin é onde encontramos o arquivo principal para rodar nossa aplicação.

    É onde encontramos o arquivo com o mesmo nome do projeto, mas o ideal é que aqui tenha apenas um arquivo como main.dart.

    A próxima pasta é a pasta lib. É na pasta lib onde criamos as outras partes importantes para a nossa aplicação como, por exemplo, os módulos, modelos, controllers e serviços que formam toda a nossa aplicação.

    A pasta test é autoexplicativa. É onde criamos todos os testes da nossa aplicação.

    Dos arquivos externos, apenas dois são importantes para nós em um nível básico:

    • pubspec.yaml;
    • README.md.

    O arquivo pubspec.yaml é onde dizemos para o Dart onde encontrar recursos como imagens, fontes e módulos externos.

    Também é nesse arquivo que dizemos quais bibliotecas do pub.dev vamos utilizar.

    Por fim, o arquivo README.md é onde escrevemos a página inicial que ficará no GitHub.

    É importante que esse arquivo tenha uma boa descrição sobre o que é o projeto, como iniciar, quais dependências ele utiliza, entre outras informações importantes.

    Você pode conferir nosso tutorial sobre como escrever um README neste link.

    Agora você já tem tudo necessário para começar a escrever códigos em Dart.

    Tipos de dados

    Como Dart é uma linguagem fortemente tipada, é importante conhecermos os tipos básicos:

    Dart, assim como outras linguagens, consegue trabalhar com diferentes tipos de dados. É importante conhecer as palavras-chave que definem esses tipos de dados. Veja os tipos mais comuns:

    • int;
      • int é utilizado para designar números inteiros. Ex. 1, 10, -100;
    • double;
      • double é utilizado para definir números com pontos flutuantes (com casas decimais). Ex. 3.14, -2.7;
    • String;
      • String é utilizado para definir conteúdos textuais. Pode-se utilizar aspas simples ou duplas. Ex. "Matheus", 'Uma String';
    • bool;
      • bool é utilizado para definir valores booleanos como verdadeiro ou falso. Ex. true, false;
    • List;
      • List é utilizado para definir uma lista ordenada de qualquer tipo. Ex. ["Abóbora", "Cenoura"], [10, 5, 32];
    • Set;
      • Set é utilizado para definir um conjunto não ordenado de qualquer tipo. Ex. {"Abóbora", "Cenoura"};
    • Map;
      • Map é utilizado para definir objetos que possuem chave e valor. Ex. {"chave": "valor", "chave2": "outro valor"};

    Também é importante conhecer tipos especiais:

    • null;
      • null representa nada, vazio, ausência de valor;
    • dynamic;
      • dynamic representa qualquer coisa. É utilizado exatamente quando não sabemos o tipo de dado que precisamos guardar;

    Exemplo de código mostrando como declarar cada tipo falado acima:

    void main() {
      int inteiro = 10;
      double float = 2.5;
      String texto = "Um texto";
      bool sim = true;
      List lista = ["Abóbora", "Cenoura"];
      Set conjunto = {"Abóbora", "Cenoura"};
      Map objeto = {"chave": "valor", "chave2": "valor2"};
      print(inteiro);
      print(float);
      print(texto);
      print(sim);
      print(lista);
      print(conjunto);
      print(objeto);
    }
    

    Para rodar o código, você pode clicar na opção "Run" que fica em cima da função main() e ver o resultado diretamente no Debug console do Visual Studio Code.

    Outra opção é utilizar o terminal, rodando o comando dart run.

    Resposta no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    10
    2.5
    Um texto
    true
    [Abóbora, Cenoura]
    {Abóbora, Cenoura}
    {chave: valor, chave2: valor2}
    

    Nós também podemos tipar listas, conjuntos e objetos:

      List<String> lista = ["Abóbora", "Cenoura"];
      Set<String> conjunto = {"Abóbora", "Cenoura"};
      Map<String, String> objeto = {"chave": "valor", "chave2": "valor2"};
    

    É sempre muito importante dizer para o Dart que tipo de informação que estamos trabalhando.

    Na lista dizemos que estamos trabalhando com uma lista de String, um conjunto de String, e um objeto que tem uma chave no formato String e um valor também no formato String.

    O que acontece se a gente alterar para um tipo que não corresponde ao conteúdo? Por exemplo:

      List<bool> lista = ["Abóbora", "Cenoura"];
    

    No próprio VSCode aparecerá uma mensagem de erro dizendo que tipo String não pode ser atribuído para valores bool.

    Uma captura de tela mostrando código na linguagem de programação Dart dentro de um IDE com destaque de sintaxe. O código inclui declarações de variáveis de diferentes tipos, como inteiros, doubles, strings e booleanos, além de coleções como listas e conjuntos contendo elementos de string. Duas linhas estão marcadas com indicadores de erro, sugerindo incompatibilidades de tipos nas atribuições.

    Mas agora vem uma parte muito interessante do Dart! Veja o exemplo a seguir:

    List<dynamic> lista = ["Abóbora", 4, true];
    

    O código acima não dá erro. O Dart permite criar listas que possuem valores diferentes e isso não é algo exclusivo para listas, visto que os conjuntos e objetos também podem trabalhar com dynamic.

    E não precisamos declarar variáveis como dynamic. Podemos utilizar a palavra-chave var (como no JavaScript).

      var umValor = bool;
    

    Veja um exemplo muito comum:

    Map<String, dynamic> objeto = {
        "chave": {"chave": "valor"},
        "outra chave": bool
      };
    

    Não foque muito nos valores, mas foque na estrutura de Map<String, dynamic>. Essa estrutura é super usada quando trabalhamos com banco de dados ou informações da internet.

    Normalmente nós transformamos os dados em objetos para trabalhar dentro do Dart. Vamos entender melhor quando entrarmos em classes.

    Funções

    Funções também são muito importantes de serem aprendidas e, conhecer a sua estrutura, é essencial para criar aplicações dinâmicas.

    Nós já vimos um exemplo de funções no começo do artigo, mas vamos aprofundar um pouco mais, entendendo como funciona a sua estrutura e como podemos fazer funções mais robustas e complexas.

    Veja um exemplo de criação de uma função:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      void calcular() {
        print(valor1 + valor2);
      }
      calcular();
    }
    

    O código acima é uma aplicação que tem dois valores inteiros declarados, uma função sem retorno e seu corpo chama a função do Dart print para mostrar informações no console, somando os dois valores declarados anteriormente.

    Para declarar uma função, primeiro precisamos dizer o tipo de retorno, que neste caso é void, depois o nome da função e por último o corpo da função.

    Podemos pensar nesta estrutura:

    retorno nome() {
      corpo;
    }
    

    No exemplo anterior, nós estávamos calculando a soma de duas variáveis fora da função, mas podemos deixar a função mais dinâmica passando valores como atributo. Veja o exemplo:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      void calcular(a, b) {
        print(a + b);
      }
      calcular(valor1, valor2);
    }
    

    Neste caso, a função calcular recebe dois valores: a e b. A vantagem dessa prática, é que essa função não fica presa a apenas somar as variáveis valor1 e valor2, nós agora podemos passar quaisquer valores que a função imprimirá a soma deles.

    Mas esse é um detalhe importante: qualquer valor. Isso quer dizer que podemos passar conteúdos textuais (Strings) ou booleanos, e isso não deveria ser possível.

    Existe outra funcionalidade de funções, onde podemos tipar os valores que recebemos dentro da função. Veja o exemplo abaixo:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      void calcular(int a, int b) {
        print(a + b);
      }
      calcular(valor1, valor2);
    }
    

    Neste exemplo, nós passamos dois valores para a função calcular e também passamos o tipo de dado que a função precisa receber, que neste caso serão números inteiros.

    Assim, garantimos que a função vai trabalhar apenas com números inteiros, tornando nosso código mais seguro e robusto.

    Escopo de código

    Vou dar a seguinte situação: você está numa escola em uma sala de aula. Tudo que você precisa para estudar (mesa, lousa, etc) existe dentro da sua sala; outras salas também têm essas coisas.

    Nessa escola também existe um pátio onde todas as pessoas vão se alimentar, brincar, conversar, etc. Guarde essa situação em sua memória.

    Vamos ver agora um exemplo de código:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      void calcular(int a, int b) {
        int soma = a + b;
      }
      calcular(valor1, valor2);
      print(soma);
    }
    

    Tentando rodar o código acima teremos um erro de compilação. O Dart vai dizer que a variável soma não existe dentro do contexto da função print().

    Agora voltando para o contexto da escola. Podemos relacionar a função main como se fosse o pátio da escola, ou seja, todas as pessoas estudantes têm acesso.

    Já a função calcular, é como se fosse uma sala de aula, ou seja, apenas estudantes daquela sala têm acesso.

    Isso quer dizer que as variáveis valor1 e valor2 podem ser acessadas por toda a aplicação, mas a variável soma só pode ser acessada dentro da função calcular.

    Nós chamamos essas limitações de escopo e é muito importante ter consciência dessa funcionalidade para evitar problemas como o que tivemos com o código acima, mas isso não quer dizer que queremos criar todas as variáveis globais (na função main)!

    É algo que deve ser questionado com outras pessoas da equipe para ver a melhor forma de desenvolver o código.

    Vamos ver algumas formas que podemos lidar com escopo:

    Uma solução seria deixar a variável soma no escopo global da aplicação:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      int soma = 0;
      void calcular(int a, int b) {
        soma = a + b;
      }
      calcular(valor1, valor2);
      print(soma);
    }
    

    Existem alguns problemas nessa solução. Por ora, a nossa aplicação é pequena e faz apenas esse cálculo, mas pode ser que em aplicações maiores, nós precisemos criar várias variáveis chamada soma em contextos diferentes.

    Uma das coisas mais difíceis na vida de uma pessoa programadora é nomear coisas. Portanto, se pudermos evitar criar restrições para nós mesmos(as), melhor.

    Uma outra possibilidade que nós temos é transformar a função de forma que ela retorne um valor.

    Como estamos trabalhando com a soma de dois valores inteiros, então podemos dizer que a função vai retornar um valor inteiro.

    Depois podemos guardar o resultado (ou retorno) em outra variável. Veja o exemplo:

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      int soma;
      int calcular(int a, int b) {
        int soma = a + b;
        return soma;
      }
      soma = calcular(valor1, valor2);
      print(soma);
    }
    

    Porém, veja que ainda estamos utilizando duas somas. Isso ainda pode ficar confuso. Então, vamos melhorar ainda mais fazendo o resultado da soma ser retornado diretamente. Além disso, podemos imprimir a função diretamente dentro da função de print():

    void main() {
      int valor1 = 10;
      int valor2 = 5;
      int calcular(int a, int b) {
        return a + b;
      }
      print(calcular(valor1, valor2));
    }
    

    Laços de repetição

    Vão existir situações que queremos trabalhar com repetições como, por exemplo, percorrer por valores de uma lista.

    Existem algumas maneiras de trabalhar com repetições, mas é importante saber que repetições precisam de uma condição de encerramento.

    Vamos ver algumas formas que temos de trabalhar com repetição no Dart.

    Laço com for

    A função for é composta por 4 partes principais:

    • Uma função ou execução inicial;
    • Uma condição de encerramento;
    • Uma função ou execução no final de cada iteração;
    • O corpo do for (o que será executado a cada iteração).

    Vamos ver o exemplo de um for em Dart:

    void main() {
      for (var i = 0; i < 5; i++) {
        print(i);
      }
    }
    

    Na primeira parte, estamos declarando a variável i e inicializando ela com o valor 0. Depois estamos verificando se i é menor que 5.

    Em seguida, fazemos a impressão da variável i. Depois executamos i++ que vai simplesmente adicionar 1 à variável i. Depois voltamos para a condição e continuamos nesse ciclo até que a condição i < 5 se torne falsa.

    Detalhe interessante sobre escopo: a variável i está sendo declarada dentro do for, portanto ela não pode ser acessada fora do escopo da função for.

    Eu tinha falado sobre utilizar for para iterar sobre valores de uma lista, então vamos ver esse exemplo em ação:

    void main() {
      List<String> listaDeCompras = ["Abóbora", "Arroz", "Sal", "Alho", "Pepino", "Alface"];
      for (var i = 0; i < listaDeCompras.length; i++) {
        print(listaDeCompras[i]);
      }
    }
    

    No exemplo acima, nós temos uma lista de compras do tipo String que contém os itens Abóbora, Arroz, Sal, Alho, Pepino e Alface.

    Dentro do for nós vamos comparar o valor de i com o tamanho da lista. Para cada iteração do for, nós estamos imprimindo o item da lista listaDeCompras na posição que se encontra i.

    Dentro do console temos o seguinte resultado:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    Abóbora
    Arroz
    Sal
    Alho
    Pepino
    Alface
    

    Cuidado que a primeira posição de listas é sempre a posição 0.

    Laços com while

    O Dart também tem outra forma de laço de repetição com while. A estrutura é um pouco diferente que o for, mas ainda segue o princípio de que uma condição de término precisa existir.

    Vamos ver um exemplo de código:

    void main() {
      int contador = 0;
      while (contador < 5) {
        print(contador);
        contador++;
      }
    }
    
    • int contador = 0;: Declaramos uma variável contador do tipo inteiro e inicializamos com o valor 1.
    • while (contador < 5) { ... }: Este é o loop while. Ele vai continuar executando o bloco de código dentro das chaves {...} enquanto a condição contador <= 5 for verdadeira.
      • print(contador);: Imprime o valor atual do contador no console.
      • contador++;: Incrementa o valor do contador em 1 a cada iteração. Isso é importante para que o loop não continue infinitamente.
    • Quando o contador se torna 5, a condição contador < 5 não é mais verdadeira e o loop termina.

    Este é um exemplo básico, mas demonstra como usar o loop while para executar um bloco de código repetidamente até que uma determinada condição se torne falsa.

    Incrementando o while colocando nossa lista na receita:

    void main() {
      List<String> listaDeCompras = ["Abóbora", "Arroz", "Sal", "Alho", "Pepino", "Alface"];
      int contador = 0;
      while (contador < listaDeCompras.length) {
        print(listaDeCompras[contador]);
        contador++;
      }
    }
    

    As estruturas de um for e um while são bem parecidas, mas as situações de uso são diferentes. Podemos utilizar for para percorrer coisas "com tamanho" ou com alguma contagem.

    Listas tem um tamanho. Agora while continua executando até que algo diga que precisa parar.

    Um exemplo seria: enquanto a tecla "w" for pressionada, mova o objeto para frente. A condição não é algo que podemos contar.

    Do While

    Existe uma versão mais complicada do while. O do while! Vamos ver um exemplo:

    void main() {
      int contador = 6;
      do {
        print(contador);
        contador++;
      } while (contador <= 5);
    }
    
    • int contador = 6;: Declaramos uma variável contador do tipo inteiro e inicializamos com o valor 6.
    • do { ... } while (contador <= 5);: Este é o loop do while. Ele executa o bloco de código dentro das chaves {...} pelo menos uma vez, e então verifica a condição contador <= 5.
      • print(contador);: Imprime o valor atual do contador na console (nesse caso, será impresso 6).
      • contador++;: Incrementa o valor do contador em 1.
    • Depois da primeira execução, a condição contador <= 5 se torna falsa (já que o contador é 7), e o loop termina.

    Mesmo que a condição inicial (contador <= 5) seja falsa, o loop do while sempre garante que o bloco de código seja executado pelo menos uma vez.

    Isso é útil em situações onde você precisa executar um código pelo menos uma vez, e então verificar uma condição para continuar as iterações.

    Classes

    Dart é uma linguagem que segue bastante os paradigmas de Orientação à Objetos. Portanto, podemos criar representações de coisas utilizando classes. Vamos ver um exemplo de uma classe que representa uma conta bancária.

    class Account {
      int id = 1;
      String cpf = "333.333.333-33";
      String name = "Matheus";
      double balance = 1000.00;
    }
    

    Criei uma classe conta que possui as seguintes propriedades e valores:

    • Um id que é um número inteiro e tem o valor 1;
    • Um cpf que é uma String e tem o valor "333.333.333-33";
    • Um nome que é uma String e tem o valor "Matheus";
    • Um balanço que é um valor de ponto flutuante (double) e tem o valor 1000.00;

    Podemos acessar os valores desta conta através da criação de uma instância:

    // meu_app.dart
    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account();
      print(account.name);
    }
    
    • Primeiro precisamos importar a classe Account dentro do arquivo principal meu_app.dart;
    • Dentro da função nós criamos uma instância do tipo Account chamada account;
    • Acessamos as propriedades chamando a instância + a propriedade.

    Aqui entra um ponto importante com relação à estrutura de arquivos do Dart. Todas as classes novas, modelos e outras representações ou partes da aplicação, precisam ficar dentro da pasta lib.

    Só que a conta que foi criada e instanciada, tem os seus valores fixos. O ideal é que uma classe seja um modelo e que outras instâncias tenham seus próprios valores.

    Nós passamos novos valores para uma classe através do método construtor. No Dart nós podemos chamar esse construtor da seguinte maneira:

    class Account {
      int id;
      String cpf;
      String name;
      double balance;
      Account(this.id, this.cpf, this.name, this.balance);
    }
    

    Agora quando vamos criar uma nova instância de Account, passamos os devidos valores que compõem essa nossa conta:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(1, "333.333.333-33", "Matheus", 1000);
      print(account.name);
    }
    

    Atributos nomeados

    Em Dart, nós temos duas maneiras de passar informações para dentro de uma classe no momento da sua instância.

    A forma comum que fizemos até agora, onde temos que colocar os valores na mesma ordem que aparecem no construtor, e a forma nomeada.

    Utilizamos dentro do construtor o conjunto de chaves, e dentro dele, cada uma das propriedades que existem na classe:

    class Account {
      int id;
      String cpf;
      String name;
      double balance;
      Account({required this.id, required this.cpf, required this.name, required this.balance});
    }
    

    Quando criamos uma instância, agora não importa mais a ordem dos parâmetros mas sim o seu nome. Veja como fica a criação de uma nova instância de Account:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", name: "Matheus", balance: 1000);
      print(account.name);
    }
    

    Detalhe importante é que quando usamos atributos nomeados, precisamos colocar a palavra-chave required, que significa "necessário". Dart, assim como outras linguagens, não gosta de valores nulos (o tipo especial null que falamos antes).

    Dart e o Null safety

    O Dart tem uma ferramenta muito incrível para lidar com valores nulos. Vamos dizer que a nossa classe Account pode ter a propriedade name vazia.

    Pensando no mundo real, o mais importante para identificar uma pessoa é o CPF e nomes podem se repetir. Só que quando criamos uma instância, precisamos passar um valor para nome, mesmo que seja apenas uma String vazia.

    Para sinalizar o Dart que alguma propriedade de uma classe pode não receber valores na sua instância, utilizamos o símbolo de interrogação (?).

    Veja o exemplo a seguir:

    class Account {
      int id;
      String cpf;
      String? name;
      double balance;
      Account({required this.id, required this.cpf, this.name, required this.balance});
    }
    

    Através do símbolo ? conseguimos dizer para o Dart que o valor da propriedade name pode ser nula. Isso quer dizer que quando vamos criar uma instância de Account, não precisamos passar o atributo name. Veja como fica a criação de uma instância de Account:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", balance: 1000);
      print(account.name);
    }
    

    Se a gente rodar o código agora, o valor de account.name é um valor nulo. Veja o resultado no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    null
    

    Lógico que permitir valores nulos pode ser perigoso se não utilizado corretamente, mas uma parte muito interessante do Dart é a robustez de uma linguagem como Java e a maleabilidade e flexibilidade de uma linguagem como JavaScript.

    Vamos ver rapidamente uma forma de nos proteger de valores nulos. Dentro do construtor podemos atribuir um valor padrão que será utilizado caso nenhum valor seja passado no processo de criação de uma instância.

    Veja o exemplo passando o valor "Unknown" para a propriedade name:

    class Account {
      int id;
      String cpf;
      String? name;
      double balance;
      Account({
        required this.id,
        required this.cpf,
        this.name = "Unknown",
        required this.balance,
      });
    

    Quando executamos o código sem definir um valor para name, temos a seguinte mensagem no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    Unknown
    

    Criando uma instância passando um nome:

    Agora quando criamos uma instância passando um valor para a propriedade name:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", balance: 1000, name: "James");
      print(account.name);
    }
    

    Temos o seguinte resultado no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    James
    

    Null Safety é uma ferramenta muito versátil do Dart, que permite que nosso código tenha uma grande maleabilidade, mas também é muito importante não utilizar em excesso ou sem muita necessidade, pois pode deixar nosso código "fraco".

    Alterando propriedades

    Bom, vimos até agora como criar instâncias, mas como podemos alterar valores depois que uma instância foi criada?

    Podemos alterar valores das propriedades de uma instância simplesmente chamando o nome da instância (objeto) mais o nome da propriedade e depois atribuir um novo valor:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", balance: 1000, name: "James");
      print(account.balance);
      account.balance = 300;
      print(account.balance);
    }
    

    Executando o código acima temos o seguinte resultado no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    1000.0
    300.0
    

    Valores constantes

    O Dart também tem uma forma de impedir que valores sejam modificados após a criação de uma instância. Podemos sinalizar que uma propriedade tem o seu valor imutável através da palavra-chave final:

    class Account {
      final int id;
      final String cpf;
      final String? name;
      final double balance;
      Account({
        required this.id,
        required this.cpf,
        this.name = "Unknown",
        required this.balance,
      });
    }
    

    Podemos tentar alterar o valor da propriedade balance da seguinte maneira:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", balance: 1000, name: "James");
      print(account.balance);
      account.balance = 300;
      print(account.balance);
    }
    

    E isso acaba gerando um erro agora no código, dizendo que não podemos alterar o valor de propriedades constantes.

    Detalhe que eu falei constantes mas utilizei a palavra-chave final. A palavra-chave const é utilizada em classes abstratas.

    Propriedades privadas

    O Dart também permite a criação de propriedades privadas. Utilizamos propriedades privadas para impedir que funções ou chamadas de código fora da classe, tenham acesso aos valores de uma propriedade de uma classe.

    Veja como podemos transformar a propriedade balance em uma propriedade privada:

    class Account {
      int id;
      String cpf;
      String? name;
      double _balance = 1000;
      Account({
        required this.id,
        required this.cpf,
        this.name = "Unknown",
      });
    }
    

    Um detalhe muito importante é que diferente de outras linguagens que existe a palavra-chave private, o Dart segue um padrão bem parecido com o JavaScript. Colocamos um underscore/underline (_) antes do nome da propriedade.

    Porém, cuidado porque o underscore precisa estar junto com o nome da propriedade, sem espaços.

    Agora tentando imprimir o valor de _balance:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", name: "James");
      print(account._balance);
    }
    

    O código acima vai dar um erro dizendo que não consegue encontrar a propriedade _balance. Isso porque agora ela está privada!

    Métodos de uma classe

    Além de propriedades, uma classe também pode ter métodos. Métodos de uma classe são funções que definem ações que um objeto pode ter.

    Pensando em contas, uma conta pode realizar uma transferência. Essa é uma ação apenas dela.

    Podemos criar o método de transferência para a classe Account da seguinte maneira:

    class Account {
      int id;
      String cpf;
      String? name;
      double balance;
      Account({
        required this.id,
        required this.cpf,
        this.name = "Unknown",
        required this.balance,
      });
      void transfer(double amount) {
        balance = balance - amount;
      }
    }
    

    Agora podemos realizar uma transferência chamando a função transfer da seguinte maneira:

    import 'package:meu_app/account.dart';
    void main() {
      Account account = Account(id: 1, cpf: "333.333.333-33", balance: 1000, name: "James");
      print(account.balance);
      account.transfer(100);
      print(account.balance);
    }
    

    Executando o código acima temos o seguinte resultado no console:

    ❯ dart run
    Building package executable... 
    Built meu_app:meu_app.
    1000.0
    900.0
    

    Instalando pacotes

    O Dart tem um gerenciador de pacotes muito simples de utilizar. Novamente fazendo uma comparação com o npm do JavaScript, o pub.dev guarda todos os repositórios de bibliotecas criadas pela comunidade e até mesmo por equipes do Dart.

    Para instalar pacotes nós temos duas opções principais:

    Adicionando o pacote no pubspec

    Lembra daquele arquivo pubspec.yaml? É nele que ficam as informações de como rodar e atualizar a aplicação, bem parecido com o arquivo package.json de projetos JavaScript.

    name: meu_app
    description: A sample command-line application.
    version: 1.0.0
    # repository: https://github.com/my_org/my_repo
    environment:
      sdk: ^3.3.3
    # Add regular dependencies here.
    dependencies:
      # path: ^1.8.0
    dev_dependencies:
      lints: ^3.0.0
      test: ^1.24.0
    

    O código acima é meu arquivo pubspec.yaml. Para adicionar o pacote http, podemos adicionar uma nova entrada na categoria de dependencies:

    name: meu_app
    description: A sample command-line application.
    version: 1.0.0
    # repository: https://github.com/my_org/my_repo
    environment:
      sdk: ^3.3.3
    # Add regular dependencies here.
    dependencies:
      # path: ^1.8.0
      http: ^1.2.1
    dev_dependencies:
      lints: ^3.0.0
      test: ^1.24.0
    

    Importante seguir os padrões de escrita de um documento YAML!

    Logo em seguida, a IDE deve buscar automaticamente os pacotes novos adicionados. Caso isso não tenha acontecido, podemos forçar uma busca com o comando no terminal:

    dart pub get
    
    ❯ dart pub get
    Resolving dependencies... 
      _fe_analyzer_shared 67.0.0 (68.0.0 available)
      analyzer 6.4.1 (6.5.0 available)
      lints 3.0.0 (4.0.0 available)
    Got dependencies!
    3 packages have newer versions incompatible with dependency constraints.
    Try `dart pub outdated` for more information.
    

    Uma vantagem que temos de adicionar manualmente no arquivo pubspec.yaml é que temos controle total da versão que estamos baixando. Podemos também adicionar vários pacotes de uma só vez ao invés de instalar um por um pelo terminal.

    Utilizando o terminal

    Para instalar pelo terminal, podemos utilizar o seguinte comando:

    dart pub add logger
    

    Ele vai adicionar automaticamente dentro do arquivo pubspec.yaml uma entrada da biblioteca logger.

    name: meu_app
    description: A sample command-line application.
    version: 1.0.0
    # repository: https://github.com/my_org/my_repo
    environment:
      sdk: ^3.3.3
    # Add regular dependencies here.
    dependencies:
      # path: ^1.8.0
      http: ^1.2.1
      logger: ^2.3.0
    dev_dependencies:
      lints: ^3.0.0
      test: ^1.24.0
    

    Em teoria, rodando o comando no terminal deve acontecer automaticamente a instalação do pacote, mas caso não aconteça, você pode rodar o comando dart pub get em seguida.

    Desvantagens do Dart

    Infelizmente nem tudo são flores. Dart tem algumas desvantagens, assim como toda outra linguagem. Por exemplo:

    Comunidade pequena

    Dart ainda é uma linguagem relativamente nova comparada à outras linguagens como Java, Python ou JavaScript. Isso quer dizer que recursos, pacotes, suporte e ferramentas de aprendizado são mais escassos.

    Menor adoção por empresas

    O Dart ainda não é tão amplamente adotado por empresas quanto outras linguagens. Isso pode dificultar de encontrarmos oportunidades de trabalho em algumas áreas.

    Falta de padronização de bibliotecas

    Algumas bibliotecas de terceiros para Dart ainda podem estar em desenvolvimento ou não ter o mesmo nível de maturidade que em outras linguagens. Isso varia muito de quem está desenvolvendo a biblioteca.

    Dependência da Google

    O Dart é um projeto liderado pela Google, o que significa que algumas decisões de desenvolvimento podem estar alinhadas com os interesses da Google e não necessariamente com as necessidades da comunidade.

    Possibilidade de mudanças na linguagem

    Como o Dart é uma linguagem relativamente nova, ainda está em constante evolução e pode haver mudanças na sintaxe ou na API que podem afetar seus projetos no futuro. Isso aconteceu recentemente com a introdução do Material Design 3 para Flutter e também com o NullSafety que vimos aqui no artigo.

    Menos integração com ferramentas existentes

    A integração com ferramentas e frameworks de terceiros populares pode ser menos robusta em comparação com linguagens mais maduras.

    Resumo das desvantagens

    O maior problema no final das contas é a falta de maturidade, mas isso vai melhorando com o tempo e conforme mais empresas e pessoas desenvolvedoras vão adotando a linguagem.

    Como aprender Dart

    Se você quer evoluir no desenvolvimento mobile, chegou o momento ideal: estão abertas as inscrições para a Imersão Mobile da Alura!

    De 14 a 16 de abril, você vai aprender a desenvolver um app de delivery para Android e iOS com Flutter. Serão três aulas 100% práticas, onde cada etapa te leva para um novo nível de conhecimento, te ajudando a consolidar habilidades essenciais para sua carreira.

    Aprenda com especialistas do mercado, encare desafios reais e crie um projeto prático, colocando a mão na massa desde o primeiro dia. Evento 100% gratuito! Inscreva-se agora neste link.

    Além disso, a própria Google tem uma seção específica para quem quer aprender Dart. Você pode acessar a partir deste link, mas os tutoriais estão todos em inglês e para quem está iniciando pode ser um grande susto.

    O tutorial da Google é para quem já conhece lógica de programação e também já é uma pessoa programadora com alguma experiência em outras linguagens, não sendo uma boa opção para quem está iniciando no mundo do desenvolvimento.

    E lógico, existe a opção de aprender com a gente na Alura. Nós temos uma formação focada em ensinar Dart desde os princípios mais básicos da linguagem. Você pode conferir a formação neste link.

    Você também pode conferir os nossos artigos:

    • Construtores no Dart: conhecendo tipos de construtores e como usá-los
    • Entrada e saída de dados no terminal do Dart
    • Qual a diferença entre Static, Const e Final no Dart

    Além de artigos, também temos Alura:

    • Os 5 métodos da lista do Dart
    • Entendendo Input e Output no Dart
    • Usando o teclado para entrada e saída de dados com Dart
    • Const x Final no Dart
    • Null Safety no Dart

    Conclusão

    Dart é uma linguagem relativamente nova com muito potencial. A qualidade da documentação é incrível, instalação e manutenção de pacotes é simples, o processo de instalar e começar com Dart é indolor e acima de tudo é a base para o framework Flutter.

    Espero que este artigo tenha aumentado o seu interesse em aprender esta grande linguagem da Google, e espero encontrar você nos cursos aqui da Alura!

    Até breve!

    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    Avalie este artigo

    • Foto de Matheus Alberto

      Autor(a)

      Matheus Alberto

      Formado em Sistemas de Informação na FIAP e em Design Gráfico na Escola Panamericana de Artes e Design. Trabalho como desenvolvedor e instrutor na Alura. Nas horas vagas sou artista/ilustrador.

    Explore por tópico

    • Back-end
    • Dados
    • DevOps
    • Front-end
    • Gestão & Negócios
    • Institucionais
    • Inteligência Artificial
    • Mobile
    • UX & Design

    Leia também

    • 12/09/2024

      Diferenças entre Dart e JavaScript: entenda as linguagens

      Ler mais
    • 15/10/2024

      Boas práticas do Dart para organizar um projeto

      Ler mais
    • 15/05/2024

      Testes no Flutter: guia completo para iniciantes

      Ler mais
    Ver mais conteúdos

    Inscreva-se em nossa Newsletter

    Fique por dentro de conteúdos, insights e oportunidades do universo tech. Receba novidades e lançamentos direto no seu e-mail.

    Institucional

    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status
    Institucional
    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status

    A Alura

    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes
    A Alura
    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes

    Conteúdos

    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Conteúdos
    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Alura