Dmitry Jemerov e Svetlana Isakova Novatec
Original English language edition published by Manning Publications Co, Copyright 2017 by Manning Publications. Portuguese-language edition for Brazil copyright 2017 by Novatec Editora. All rights reserved. Edição original em Inglês publicada pela Manning Publications Co, Copyright 2017 pela Manning Publications. Edição em Português para o Brasil copyright 2017 pela Novatec Editora. Todos os direitos reservados. Novatec Editora Ltda. 2017. Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da Editora. Editor: Rubens Prates OG20170914 Tradução: Lúcia A. Kinoshita Revisão gramatical: Marta Almeida de Sá Editoração eletrônica: Carolina Kuwabata ISBN: 978-85-7522-610-0 Histórico de impressões: Setembro/2017 Primeira edição Novatec Editora Ltda. Rua Luís Antônio dos Santos 110 02460-000 São Paulo, SP Brasil Tel.: +55 11 2959-6529 Email: novatec@novatec.com.br Site: www.novatec.com.br Twitter: twitter.com/novateceditora Facebook: facebook.com/novatec LinkedIn: linkedin.com/in/novatec
Sumário Apresentação... 13 Prefácio... 15 Agradecimentos... 17 Sobre este livro... 19 Sobre os autores...23 Sobre a ilustração da capa... 24 Parte I Introdução à Kotlin... 25 Capítulo 1 Kotlin: o que é e por quê... 26 1.1 Uma amostra de Kotlin... 26 1.2 Principais características de Kotlin... 28 1.2.1 Plataformas visadas: lado do servidor, Android, qualquer lugar em que Java seja executada... 28 1.2.2 Tipagem estática... 29 1.2.3 Programação funcional e orientada a objetos... 30 1.2.4 Código gratuito e aberto... 32 1.3 Aplicações Kotlin... 32 1.3.1 Kotlin do lado do servidor... 32 1.3.2 Kotlin no Android... 34 1.4 Filosofia de Kotlin... 36 1.4.1 Pragmática... 36 1.4.2 Concisa... 37 1.4.3 Segura... 38 1.4.4 Possibilita interoperabilidade... 39 1.5 Usando as ferramentas de Kotlin... 40 1.5.1 Compilando código Kotlin... 41 5
6 Kotlin em Ação 1.5.2 Plug-in para IntelliJ IDEA e Android Studio... 42 1.5.3 Shell interativo... 42 1.5.4 Plug-in para Eclipse... 42 1.5.5 Playground online... 42 1.5.6 Conversor de Java para Kotlin... 43 1.6 Resumo... 43 Capítulo 2 Básico sobre Kotlin... 45 2.1 Elementos básicos: funções e variáveis... 45 2.1.1 Hello, world!... 46 2.1.3. Variáveis... 49 2.1.4 Formatação de strings simplificada: templates de string... 51 2.2 Classes e propriedades... 52 2.2.1 Propriedades... 53 2.2.2 Métodos de acesso personalizados... 55 2.2.3 Layout do código-fonte de Kotlin: diretórios e pacotes... 56 2.3 Representando e tratando opções: enums e when... 59 2.3.1 Declarando classes enum... 59 2.3.2 Usando when para lidar com classes enum... 60 2.3.3 Usando when com objetos arbitrários... 62 2.3.4 Usando when sem argumentos... 63 2.3.Casts inteligentes: combinando verificações de tipo e casts... 64 2.3.6 Refatoração: substituindo if por when... 66 2.3.7 Blocos como ramos de if e de when... 68 2.4 Iterando por itens: laços while e for... 69 2.4.1 Laço while... 69 2.4.2 Iterando por números: intervalos e progressões... 69 2.4.3 Iterando por mapas... 71 2.4.4 Usando in para verificar a pertinência a uma coleção ou um intervalo... 73 2.5 Exceções em Kotlin... 75 2.5.1 try, catch e finally... 76 2.5.2 try como uma expressão... 77 2.6 Resumo... 79 Capítulo 3 Definindo e chamando funções...80 3.1 Criando coleções em Kotlin... 80 3.2 Facilitando a chamada de funções... 82 3.2.1 Argumentos nomeados... 83 3.2.2 Valores default de parâmetros... 84 3.2.3 Livrando-se das classes utilitárias estáticas: funções de nível superior e propriedades.. 86
Sumário 7 3.3 Adicionando métodos às classes de outras pessoas: funções de extensão e propriedades...89 3.3.1 Importações e funções de extensão... 91 3.3.2 Chamando funções de extensão a partir de Java... 92 3.3.3 Funções utilitárias como extensões... 92 3.3.4 Sem sobrescritas para funções de extensão... 93 3.3.5 Propriedades de extensão... 95 3.4 Trabalhando com coleções: varargs, chamadas infixas e suporte de biblioteca... 97 3.4.1 Estendendo a API de coleções de Java... 97 3.4.2 Varargs: funções que aceitam um número arbitrário de argumentos... 98 3.4.3 Trabalhando com pares: chamadas infixas e declarações desestruturantes... 99 3.5 Trabalhando com strings e expressões regulares...101 3.5.1 Separando strings...101 3.5.2 Expressões regulares e strings com aspas triplas... 102 3.5.3 Strings multilinha com aspas triplas... 104 3.6 Deixando seu código organizado: funções locais e extensões... 106 3.7 Resumo... 109 Capítulo 4 Classes, objetos e interfaces... 110 4.1 Definindo hierarquias de classes...111 4.1.1 Interfaces em Kotlin...111 4.1.2 Modificadores open, final e abstract: final por padrão...114 4.1.3 Modificadores de visibilidade: public por padrão...117 4.1.4 Classes internas e aninhadas: aninhadas por padrão... 120 4.1.5 Classes seladas: definindo hierarquias de classe restritas... 122 4.2 Declarando uma classe com construtores ou propriedades não triviais... 124 4.2.1 Inicializando classes: construtor primário e blocos de inicialização... 124 4.2.2 Construtores secundários: inicializando a superclasse de modos diferentes... 128 4.2.3 Implementando propriedades declaradas em interfaces... 130 4.2.4 Acessando um backing field a partir de um getter ou de um setter... 132 4.2.5 Alterando a visibilidade de um método de acesso... 134 4.3 Métodos gerados pelo compilador: classes de dados e delegação de classe... 135 4.3.1 Métodos universais de objetos... 136 4.3.2 Classes de dados: implementações de métodos universais gerados automaticamente.139 4.3.3 Delegação de classe: usando a palavra reservada by...141 4.4 A palavra reservada object : declarando uma classe e criando uma instância ao mesmo tempo... 144 4.4.1 Declarações de objetos: simplificando os singletons... 144 4.4.2 Objetos companheiros: um local para métodos de fábrica e membros estáticos..147 4.4.3 Objetos companheiros como objetos comuns... 150 4.4.4 Expressões de objeto: uma nova versão das classes internas anônimas... 153 4.5 Resumo... 155
8 Kotlin em Ação Capítulo 5 Programação com lambdas... 156 5.1 Expressões lambda e referências a membros... 156 5.1.1 Introdução às lambdas: blocos de código como parâmetros de função... 157 5.1.2 Lambdas e coleções... 158 5.1.3 Sintaxe das expressões lambda... 160 5.1.4 Acessando variáveis no escopo... 164 5.1.5 Referências a membros... 167 5.2 APIs funcionais para coleções...169 5.2.1 Funções essenciais: filter e map...169 5.2.2 all, any, count e find: aplicando um predicado a uma coleção...172 5.2.3 groupby: convertendo uma lista em um mapa de grupos...173 5.2.4 flatmap e flatten: processando elementos em coleções aninhadas...174 5.3 Operação lazy em coleções: sequências...176 5.3.1 Executando operações em sequências: operações intermediárias e terminais...178 5.3.2 Criando sequências...181 5.4 Usando interfaces funcionais de Java... 182 5.4.1 Passando uma lambda como parâmetro a um método Java... 183 5.4.2 Construtores SAM: conversão explícita de lambdas em interfaces funcionais... 186 5.5 Lambdas com receptores: with e apply... 188 5.5.1 Função with... 188 5.5.2 Função apply... 191 5.6 Resumo... 193 Capítulo 6 Sistema de tipos de Kotlin... 194 6.1 Nulidade... 194 6.1.1 Tipos nullable... 195 6.1.2 O significado de tipos... 197 6.1.3 Operador de chamada segura:?.... 199 6.1.4 O operador Elvis:?:... 201 6.1.5 Casts seguros: as?... 203 6.1.6 Asserções de não null:!!... 204 6.1.7 A função let... 207 6.1.8 Propriedades iniciadas tardiamente... 209 6.1.9 Extensões para tipos nullable...210 6.1.10 Nulidade em parâmetros de tipo... 213 6.1.11 Nulidade e Java...214 6.2 Tipos primitivos e outros tipos básicos... 219 6.2.1 Tipos primitivos: Int, Boolean e outros... 219 6.2.2 Tipos primitivos nullable: Int?, Boolean? e outros... 221 6.2.3 Conversões de números... 222 6.2.4 Any e Any?: os tipos raiz... 224 6.2.5 O tipo Unit: o void de Kotlin... 225
Sumário 9 6.2.6 Tipo Nothing: Essa função jamais retorna... 227 6.3 Coleções e arrays... 228 6.3.1 Nulidade e coleções... 228 6.3.2 Coleções somente para leitura e coleções mutáveis... 231 6.3.3 Coleções de Kotlin e Java... 233 6.3.4 Coleções como tipos de plataforma... 236 6.3.5 Arrays de objetos e de tipos primitivos... 238 6.4 Resumo...241 Parte II Adotando Kotlin... 243 Capítulo 7 Sobrecarga de operadores e outras convenções... 244 7.1 Sobrecarregando operadores aritméticos...245 7.1.1 Sobrecarregando operações aritméticas binárias...245 7.1.2 Sobrecarregando operadores de atribuição compostos... 249 7.1.3 Sobrecarregando operadores unários... 251 7.2 Sobrecarregando operadores de comparação... 252 7.2.1 Operadores de igualdade: equals... 252 7.2.2 Operadores de ordenação: compareto... 254 7.3 Convenções usadas em coleções e intervalos... 256 7.3.1 Acessando elementos pelo índice: get e set... 256 7.3.2 A convenção in... 258 7.3.3 Convenção rangeto... 259 7.3.4 Convenção iterator para o laço for... 260 7.4 Declarações desestruturantes e funções componentes... 262 7.4.1 Declarações desestruturantes e laços... 264 7.5 Reutilizando a lógica dos métodos de acesso às propriedades: propriedades delegadas.265 7.5.1 Propriedades delegadas: o básico... 265 7.5.2 Usando propriedades delegadas: inicialização lazy e by lazy()... 267 7.5.3 Implementando propriedades delegadas... 268 7.5.4 Regras para tradução de propriedades delegadas... 273 7.5.5 Armazenando valores de propriedades em um mapa...274 7.5.6 Propriedades delegadas em frameworks...276 7.6 Resumo... 278 Capítulo 8 Funções de alta ordem: lambdas como parâmetros e valores de retorno... 279 8.1 Declarando funções de alta ordem... 279 8.1.1 Tipos função... 280 8.1.2 Chamando funções passadas como argumentos... 282 8.1.3 Usando tipos função a partir de Java... 284 8.1.4 Valores default e null para parâmetros com tipos função... 285
10 Kotlin em Ação 8.1.5 Devolvendo funções a partir de funções... 288 8.1.6 Removendo duplicações usando lambdas... 291 8.2 Funções inline: eliminando o overhead das lambdas... 293 8.2.1 Como o inline funciona... 294 8.2.2 Restrições para funções inline... 296 8.2.3 Usando operações de coleção como inline... 297 8.2.4 Decidindo quando as funções devem ser declaradas como inline... 299 8.2.5 Usando lambdas inline para gerenciamento de recursos... 300 8.3 Fluxo de controle em funções de alta ordem... 302 8.3.1 Instruções return em lambdas: retornando de uma função que a engloba... 302 8.3.2 Retornando de lambdas: return com um rótulo... 303 8.3.3 Funções anônimas: retornos locais por padrão... 305 8.4 Resumo... 307 Capítulo 9 Genéricos... 308 9.1 Parâmetros de tipo para genéricos... 309 9.1.1 Funções e propriedades genéricas...310 9.1.2 Declarando classes genéricas...312 9.1.3 Restrições para parâmetros de tipo...313 9.1.4 Fazendo com que os parâmetros de tipo sejam não null...315 9.2 Genéricos em tempo de execução: parâmetros de tipo apagados e reificados...317 9.2.1 Genéricos em tempo de execução: verificações de tipo e casts...317 9.2.2 Declarando funções com parâmetros de tipo reificados... 320 9.2.3 Substituindo referências a classes por parâmetros de tipo reificados... 323 9.2.4 Restrições para os parâmetros de tipo reificados...324 9.3 Variância: genéricos e subtipagem... 325 9.3.1 Por que a variância existe: passando um argumento para uma função... 326 9.3.2 Classes, tipos e subtipos... 327 9.3.3 Covariância: relação de subtipagem preservada... 329 9.3.4 Contravariância: relação inversa de subtipagem... 334 9.3.5 Variância no local de uso: especificando a variância nas ocorrências dos tipos. 337 9.3.6 Projeção com asterisco: usando * no lugar de um argumento de tipo...341 9.4 Resumo... 346 Capítulo 10 Anotações e reflexão... 348 10.1 Declarando e aplicando anotações... 349 10.1.1 Aplicando anotações... 349 10.1.2 Alvos das anotações... 350 10.1.3 Usando anotações para personalizar a serialização de JSON... 353 10.1.4 Declarando anotações... 356 10.1.5 Meta-anotações: controlando o processamento de uma anotação... 357
Sumário 11 10.1.6 Classes como parâmetros de anotações... 358 10.1.7 Classes genéricas como parâmetros de anotações... 360 10.2 Reflexão: introspecção de objetos Kotlin em tempo de execução... 361 10.2.1 A API de reflexão Kotlin: KClass, KCallable, KFunction e KProperty... 362 10.2.2 Implementando a serialização de objetos usando reflexão... 366 10.2.3 Personalizando a serialização com anotações... 368 10.2.4 Parsing de JSON e desserialização de objetos... 372 10.2.5 Último passo da desserialização: callby() e a criação de objetos usando reflexão.. 377 10.3 Resumo... 382 Capítulo 11 Construção de DSLs... 383 11.1 De APIs a DSLs... 383 11.1.1 O conceito de linguagens de domínio específico... 385 11.1.2 DSLs internas... 387 11.1.3 Estrutura das DSLs... 388 11.1.4 Construindo HTML com uma DSL interna... 389 11.2 Construindo APIs estruturadas: lambdas com receptores em DSLs...391 11.2.1 Lambdas com receptores e tipos função de extensão...391 11.2.2 Usando lambdas com receptores em builders de HTML... 396 11.2.3 Builders de Kotlin: possibilitando abstração e reutilização... 401 11.3 Blocos aninhados de modo mais flexível usando a convenção invoke... 404 11.3.1 A convenção invoke : objetos callable como funções... 404 11.3.2 A convenção invoke e os tipos funcionais... 405 11.3.3 A convenção invoke em DSLs: declarando dependências no Gradle... 407 11.4 DSLs em Kotlin na prática... 409 11.4.1 Encadeando chamadas infixas: should em frameworks de teste... 409 11.4.2 Definindo extensões em tipos primitivos: tratando datas...412 11.4.3 Funções de extensão membros: DSL interna para SQL...413 11.4.4 Anko: criando UIs para Android dinamicamente...417 11.5 Resumo...419 Apêndice A Construindo projetos em Kotlin... 420 A.1 Construção de código Kotlin com o Gradle... 420 A.1.1 Construindo aplicações Android em Kotlin com o Gradle...421 A.1.2 Construindo projetos que usam processamento de anotações... 422 A.2 Construção de projetos Kotlin com o Maven... 423 A.3 Construção de código Kotlin com o Ant... 423 Apêndice B Documentação de código Kotlin... 425 B.1 Escrevendo comentários para documentação de Kotlin... 425 B.2 Gerando a documentação da API... 427
12 Kotlin em Ação Apêndice C Ecossistema de Kotlin... 429 C.1 Testes... 429 C.2 Injeção de dependências... 430 C.3 Serialização de JSON... 430 C.4 Clientes HTTP... 430 C.5 Aplicações web...431 C.6 Acesso a banco de dados...431 C.7 Utilitários e estruturas de dados... 432 C.8 Programação para desktop... 432