Capitulo 9788575226100

Page 1

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


capítulo 1

Kotlin: o que é e por quê

Este capítulo inclui: • uma demonstração básica de Kotlin; • as principais características da linguagem Kotlin; • possibilidades de desenvolvimento para Android e do lado do servidor; • o que distingue Kotlin de outras linguagens; • como escrever e executar código em Kotlin. De que se trata Kotlin? É uma nova linguagem de programação voltada para a plataforma Java. Kotlin é uma linguagem concisa, segura, pragmática, com enfoque na interoperabilidade com código Java. Ela pode ser usada em quase todos os lugares em que Java é utilizada atualmente: em desenvolvimentos do lado do servidor, aplicações para Android e muito mais. Kotlin funciona muito bem com todas as bibliotecas e os frameworks Java desenvolvidos e executa apresentando o mesmo nível de desempenho que Java. Neste capítulo exploraremos as principais características de Kotlin em detalhes.

1.1 Uma amostra de Kotlin Vamos começar com um pequeno exemplo para mostrar a aparência de Kotlin. Esse exemplo define uma classe Person, cria uma coleção de pessoas, encontra a pessoa mais velha e exibe o resultado. Mesmo nesse pequeno trecho de código, podemos ver muitos recursos interessantes de Kotlin; destacamos alguns deles para que você possa localizá-los facilmente mais adiante no livro. O código será explicado rapidamente, mas, por favor, não se preocupe caso haja algo que não esteja claro de imediato. Discutiremos tudo em detalhes depois. 26


Capítulo 1 ■ Kotlin: o que é e por quê

27

Se você quiser tentar executar esse exemplo, a opção mais simples é usar o playground online em http://try.kotl.in. Digite o exemplo, clique no botão Run (Executar), e o código será executado. Listagem 1.1 – Uma amostra inicial de Kotlin data class Person(val name: String, u val age: Int? = null) v fun main(args: Array<String>) { w val persons = listOf(Person("Alice"), Person("Bob", age = 29)) x val oldest = persons.maxBy { it.age ?: 0 } y println("The oldest is: $oldest") z } // The oldest is: Person(name=Bob, age=29) {

u Classe data. v Tipo nullable (Int?); o valor default para o argumento. w Função de nível superior. x Argumento nomeado. y Expressão lambda; operador Elvis. z Template de string. { toString gerado automaticamente.

Declaramos uma classe de dados simples com duas propriedades: name e age. A propriedade age é null por default (se não for especificada). Ao criar a lista de pessoas, a idade de Alice foi omitida, portanto o valor default null foi usado. Em seguida usamos a função maxBy para encontrar a pessoa mais velha da lista. A expressão lambda passada para a função aceita um parâmetro, e usamos it como o nome default desse parâmetro. O operador Elvis (?:) devolve zero se age for null. Como a idade de Alice não foi especificada, o operador Elvis a substituiu por zero, portanto Bob é o vencedor por ser a pessoa mais velha. Você gostou do que viu? Continue lendo para saber mais e se tornar um expert em Kotlin. Esperamos que em breve você veja um código como esse em seus próprios projetos, e não apenas neste livro.


28

Kotlin em Ação

1.2 Principais características de Kotlin Provavelmente você já tem uma ideia do tipo de linguagem que é Kotlin. Vamos observar seus principais atributos com mais detalhes. Inicialmente, veremos os tipos de aplicação que você pode construir com Kotlin.

1.2.1 Plataformas visadas: lado do servidor, Android, qualquer lugar em que Java seja executada O principal objetivo de Kotlin é oferecer uma alternativa mais concisa, mais produtiva e mais segura a Java, que seja apropriada em todos os contextos em que Java é usada atualmente. Java é uma linguagem extremamente popular e é utilizada em uma ampla variedade de ambientes, desde smart cards (cartões inteligentes, com tecnologia Java Card) até os maiores data centers administrados por Google, Twitter, LinkedIn e outras empresas em escala de internet. Na maioria desses lugares, usar Kotlin pode ajudar os desenvolvedores a atingir seus objetivos com menos código e menos aborrecimentos no caminho. As áreas mais comuns para usar Kotlin são: • construir código do lado do servidor (geralmente backends para aplicações web); • construir aplicativos móveis que executem em dispositivos Android. Entretanto Kotlin funciona também em outros contextos. Por exemplo, podemos usar a Intel Multi-OS Engine (https://software.intel.com/en-us/multi-os-engine) para executar código Kotlin em dispositivos iOS. Para construir aplicações desktop, podemos usar Kotlin com TornadoFX (https://github.com/edvin/tornadofx) e JavaFX.1 Além de Java, Kotlin pode ser compilada para JavaScript, permitindo que você execute código Kotlin no navegador. Porém, atualmente (na época em que este livro está sendo escrito), o suporte a JavaScript ainda está sendo explorado e em fase de protótipos na JetBrains, portanto, estará fora do escopo deste livro. Outras plataformas também estão sendo consideradas para futuras versões da linguagem. Como podemos ver, o alvo de Kotlin é bem amplo. Kotlin não tem um único domínio de problema como foco, nem trata um único tipo de desafio enfrentado pelos desenvolvedores de software atualmente. Em vez disso, a linguagem oferece melhorias de produtividade em todos os sentidos, para todas as tarefas que surgirem durante o processo de desenvolvimento. Ela oferece um excelente nível de 1 “JavaFX: Getting Started with JavaFX” (JavaFX: introdução a JavaFX), Oracle, http: //mng. bz/500y.


Capítulo 1 ■ Kotlin: o que é e por quê

29

integração com bibliotecas para suporte a domínios ou paradigmas de programação específicos. Em seguida vamos ver as principais qualidades de Kotlin como linguagem de programação.

1.2.2 Tipagem estática Assim como Java, Kotlin é uma linguagem de programação estaticamente tipada. Isso significa que o tipo de toda expressão em um programa é conhecido em tempo de compilação, e o compilador é capaz de validar se os métodos e campos que você está tentando acessar existem nos objetos que você estiver usando. Isso contrasta com as linguagens de programação dinamicamente tipadas, representadas na JVM por Groovy e JRuby, entre outras. Essas linguagens permitem definir variáveis e funções que podem armazenar ou devolver dados de qualquer tipo e resolvem as referências a métodos e campos em tempo de execução. Esse recurso permite ter códigos menores e mais flexibilidade na criação de estruturas de dados. A desvantagem, porém, é que problemas como nomes com erros de digitação não podem ser detectados durante a compilação e podem resultar em erros em tempo de execução. Por outro lado, em oposição a Java, Kotlin não exige que você especifique o tipo de toda variável explicitamente em seu código-fonte. Em muitos casos, o tipo de uma variável pode ser determinado automaticamente a partir do contexto, permitindo omitir a sua declaração. Eis o exemplo mais simples possível desse caso: val x = 1

Você está declarando uma variável e, como ela é inicializada com um valor inteiro, Kotlin determina automaticamente que seu tipo é Int. A capacidade do compilador de determinar tipos com base no contexto é chamada de inferência de tipos (type inference). A seguir, apresentamos algumas das vantagens da tipagem estática: • Desempenho – A chamada de métodos é mais rápida porque não há necessi-

dade de descobrir qual método deve ser chamado em tempo de execução. • Confiabilidade – O compilador verifica se o programa está correto, portanto

há menos chances de falhas em tempo de execução. • Manutenibilidade – Trabalhar com um código desconhecido é mais fácil porque

podemos ver os tipos de objetos com os quais o código está lidando. • Suporte de ferramentas – A tipagem estática permite refatorações confiáveis, pre-

enchimento automático de código de forma precisa e outros recursos de IDE.


30

Kotlin em Ação

Graças ao suporte de Kotlin para inferência de tipos, a maior parte da verbosidade extra associada à tipagem estática desaparece, pois não será necessário declarar os tipos explicitamente. Se observar as especificidades do sistema de tipos de Kotlin, você descobrirá que há muitos conceitos conhecidos. Classes, interfaces e genéricos funcionam de maneira bem semelhante a Java, portanto a maior parte de seu conhecimento de Java deverá ser facilmente transferida para Kotlin. Entretanto há algumas novidades. A mais importante delas é o suporte de Kotlin para tipos nullable, que permite escrever programas mais confiáveis ao detectar possíveis exceções de ponteiros null em tempo de compilação. Voltaremos aos tipos nullable mais adiante neste capítulo, e eles serão discutidos com detalhes no Capítulo 6. Outra novidade no sistema de tipos de Kotlin é seu suporte para tipos de função. Para saber o que isso quer dizer, vamos dar uma olhada nas principais ideias da programação funcional e ver como Kotlin oferece suporte a ela.

1.2.3 Programação funcional e orientada a objetos Como desenvolvedor Java, sem dúvida, você tem familiaridade com os conceitos fundamentais da programação orientada a objetos, mas a programação funcional talvez seja uma novidade. Eis os principais conceitos da programação funcional: • Funções de primeira classe – Trabalhamos com funções (porções de compor-

tamento) como valores. Podemos armazená-las em variáveis, passá-las como parâmetros ou devolvê-las a partir de outras funções. • Imutabilidade – Trabalhamos com objetos imutáveis, que garantem que seu

estado não pode ser alterado após a sua criação. • Sem efeitos colaterais – Usamos funções puras, que devolvem o mesmo resul-

tado, dadas as mesmas entradas, e não modificam o estado de outros objetos nem interagem com o mundo externo. Quais vantagens nós podemos obter escrevendo códigos no estilo funcional? Em primeiro lugar, a concisão. Um código funcional pode ser mais elegante e sucinto quando comparado à sua contrapartida imperativa, pois trabalhar com funções como valores nos proporciona muito mais capacidade de abstração, o que nos permite evitar duplicação no código. Suponha que você tenha dois fragmentos de código semelhantes que implementem uma tarefa similar (por exemplo, procurar um elemento correspondente em uma


Capítulo 1 ■ Kotlin: o que é e por quê

31

coleção), porém difiram quanto aos detalhes (de que modo o elemento correspondente é detectado). Você pode facilmente extrair a parte comum da lógica em uma função e passar as partes diferentes como argumentos. Esses argumentos, por si só, são funções, mas você pode expressá-los usando uma sintaxe concisa para funções anônimas, chamada de expressões lambda: fun findAlice() = findPerson { it.name == "Alice" } u fun findBob() = findPerson { it.name == "Bob" } v

u findPerson() contém a lógica geral para encontrar uma pessoa. v O bloco entre chaves identifica a pessoa específica que você deve encontrar.

A segunda vantagem do código funcional é o multithreading seguro. Uma das principais fontes de erro em programas multithreaded (com várias threads) é a modificação dos mesmos dados a partir de várias threads, sem uma sincronização apropriada. Se você usar estruturas de dados imutáveis e funções puras, poderá estar certo de que modificações não seguras como essas não ocorrerão, e você não precisará criar esquemas complicados de sincronização. Por fim, programação funcional significa mais facilidade nos testes. Funções sem efeitos colaterais podem ser testadas isoladamente, sem exigir muito código de configuração para construção de todo o ambiente do qual elas dependam. Falando de modo geral, o estilo funcional pode ser usado com qualquer linguagem de programação, incluindo Java, e argumenta-se que muitas partes dele constituem um bom modo de programação. Contudo nem todas as linguagens oferecem o suporte sintático e de biblioteca necessário para usá-lo sem muito esforço; por exemplo, esse suporte, em sua maior parte, não existia nas versões de Java anteriores a Java 8. Kotlin tem um conjunto rico de recursos para suporte à programação funcional desde o princípio. Esses recursos incluem: • tipos de função, que permitem que funções recebam outras funções como

parâmetros ou devolvam outras funções; • expressões lambda, que permitem passar blocos de código com mínimo de

boilerplate; • classes de dados, que possibilitam uma sintaxe concisa para criar objetos de

valores imutáveis; • um conjunto rico de APIs na biblioteca-padrão para trabalhar com objetos e coleções no estilo funcional. Kotlin permite programar no estilo funcional, mas não faz disso uma imposição.


32

Kotlin em Ação

Se for necessário, você poderá trabalhar com dados mutáveis e escrever funções que tenham efeitos colaterais, sem enfrentar grandes obstáculos. E, é claro, trabalhar com frameworks baseados em interfaces e hierarquias de classe é tão simples quanto em Java. Ao escrever código em Kotlin, você pode combinar abordagens – tanto a orientada a objetos quanto a funcional – e utilizar as ferramentas mais apropriadas ao problema que estiver sendo resolvido.

1.2.4 Código gratuito e aberto A linguagem Kotlin, incluindo o compilador, as bibliotecas e todas as ferramentas relacionadas, tem código totalmente aberto e é gratuita para uso em qualquer finalidade. Está disponível sob a licença Apache 2; o desenvolvimento ocorre abertamente no GitHub (http://github.com/jetbrains/kotlin), e contribuições por parte da comunidade são bem-vindas. Você também tem a opção para três IDEs de código aberto com a finalidade de desenvolver suas aplicações Kotlin: IntelliJ IDEA Community Edition, Android Studio e Eclipse são totalmente aceitos. (É claro que o IntelliJ IDEA Ultimate também funciona.) Agora que você já sabe que tipo de linguagem é Kotlin, vamos ver como as vantagens dessa linguagem se apresentam em aplicações práticas específicas.

1.3 Aplicações Kotlin Conforme mencionamos antes, as duas principais áreas em que Kotlin pode ser usada são no desenvolvimento do lado do servidor e para Android. Vamos observar essas duas áreas individualmente e ver por que Kotlin é bem adequada a cada uma delas.

1.3.1 Kotlin do lado do servidor Programação do lado do servidor é um conceito razoavelmente amplo. Inclui todos os tipos de aplicação a seguir e muito mais: • aplicações web que devolvem páginas HTML a um navegador; • backends para aplicativos móveis que expõem uma API JSON por meio de HTTP; • microsserviços que se comunicam com outros microsserviços por meio de um protocolo RPC.


Capítulo 1 ■ Kotlin: o que é e por quê

33

Os desenvolvedores têm construído esses tipos de aplicação em Java há vários anos, e acumularam uma pilha enorme de frameworks e tecnologias para ajudá-los nessa construção. Aplicações como essas geralmente não são desenvolvidas isoladamente nem iniciadas do zero. Quase sempre há um sistema sendo ampliado, aperfeiçoado ou substituído, e um código novo precisa ser integrado às partes já desenvolvidas do sistema, que pode ter sido escrito muitos anos antes. A grande vantagem de Kotlin nesse ambiente é sua interoperabilidade natural com código Java. Independentemente de você estar escrevendo um novo componente ou migrando o código de um serviço criado para Kotlin, essa linguagem será totalmente apropriada. Você não vai se deparar com problemas quando precisar estender classes Java em Kotlin ou fazer anotações em métodos e campos de uma classe de determinada maneira. A vantagem é que o código do sistema será mais compacto, mais confiável e mais fácil de ser mantido. Ao mesmo tempo, Kotlin possibilita usar uma série de novas técnicas para desenvolver sistemas como esses. Por exemplo, seu suporte ao padrão Builder permite criar qualquer gráfico de objeto com uma sintaxe concisa, ao mesmo tempo que preserva o conjunto completo de abstrações e ferramentas para reutilização de código da linguagem. Um dos casos de uso mais simples para essa funcionalidade é uma biblioteca de geração de HTML, capaz de substituir uma linguagem de template externa por uma solução concisa e totalmente segura para tipos. Eis um exemplo: fun renderPersonList(persons: Collection<Person>) = createHTML().table { u for (person in persons) { v tr { u td { +person.name } u td { +person.age } u } } } }

u Funções mapeadas para tags HTML. v Laço Kotlin usual.

Podemos facilmente combinar funções mapeadas para tags HTML e construções usuais da linguagem Kotlin. Não precisamos mais usar uma linguagem de template separada, com uma sintaxe diferente a ser aprendida, somente para usar um laço quando geramos uma página HTML.


34

Kotlin em Ação

Outro caso em que podemos utilizar DSLs claras e concisas de Kotlin são os frameworks para persistência. Por exemplo, o framework Exposed (https://github. com/jetbrains/exposed) oferece uma DSL fácil de ler para descrever a estrutura de um banco de dados SQL e executar consultas totalmente a partir de código Kotlin, com verificação completa de tipos. Eis um pequeno exemplo para mostrar o que é possível fazer: object CountryTable : IdTable() { u val name = varchar("name", 250).uniqueIndex() val iso = varchar("iso", 2).uniqueIndex() } class Country(id: EntityID) : Entity(id) { v var name: String by CountryTable.name var iso: String by CountryTable.iso } val russia = Country.find { w CountryTable.iso.eq("ru") }.first() println(russia.name)

u Descreve uma tabela do banco de dados. v Cria uma classe correspondente a uma entidade do banco de dados. w Você pode consultar esse banco de dados usando código Kotlin puro.

Mais adiante, veremos essas técnicas com detalhes na seção 7.5 e no Capítulo 11.

1.3.2 Kotlin no Android Um aplicativo móvel típico é bem diferente de uma aplicação corporativa típica. É muito menor, menos dependente de integração com bases de código desenvolvidas e geralmente deve ser disponibilizado de imediato, ao mesmo tempo que garante uma operação confiável em uma grande variedade de dispositivos. Kotlin também funciona muito bem em projetos desse tipo. Os recursos da linguagem Kotlin, combinados com um plug-in especial de compilador para suporte ao framework Android, faz com que o desenvolvimento para Android seja uma experiência muito mais produtiva e agradável. Tarefas comuns de desenvolvimento, como adicionar listeners em controles ou vincular elementos


Capítulo 1 ■ Kotlin: o que é e por quê

35

de layout a campos, podem ser implementadas com muito menos código ou, às vezes, sem código algum (o compilador o gerará para você). A biblioteca Anko (https://github.com/kotlin/anko), também criada pela equipe de Kotlin, proporciona uma experiência melhor ainda para você ao adicionar adaptadores adequados a Kotlin em torno de muitas APIs-padrão para Android. Eis um exemplo simples da Anko, somente para oferecer uma amostra da aparência do desenvolvimento com Kotlin para Android. Você pode colocar esse código em uma Activity, e uma aplicação simples para Android estará pronta! verticalLayout { val name = editText() u button("Say Hello") { v onClick { toast("Hello, ${name.text}!") } w } }

u Cria um campo de texto simples. v Quando clicado, esse botão exibe o valor do campo de texto. w APIs concisas para associar um listener e mostrar uma saudação.

Outra vantagem proporcionada por Kotlin é a confiabilidade na aplicação. Se você tem alguma experiência no desenvolvimento de aplicações para Android, sem dúvida, terá familiaridade com o diálogo Unfortunately, Process Has Stopped (infelizmente, o processo parou). Esse diálogo é exibido quando sua aplicação lança uma exceção não tratada – geralmente, uma NullPointerException. O sistema de tipos de Kotlin, com sua monitoração precisa de valores null, deixa o problema das exceções de ponteiros null muito menos premente. A maior parte do código que resultaria em uma NullPointerException em Java não compilará em Kotlin, garantindo que o erro seja corrigido antes que a aplicação chegue aos usuários. Ao mesmo tempo, como Kotlin é totalmente compatível com Java 6, seu uso não introduz nenhuma nova preocupação com compatibilidade. Você se beneficiará de todos os novos recursos interessantes da linguagem Kotlin, e seus usuários continuarão podendo executar sua aplicação em seus dispositivos, mesmo que não executem a versão mais recente de Android. Quanto ao desempenho, usar Kotlin tampouco traz qualquer desvantagem. O código gerado pelo compilador de Kotlin é executado de modo tão eficiente quanto um código Java usual. O runtime usado por Kotlin é relativamente pequeno, portanto você não verá um grande aumento no tamanho do pacote compilado da aplicação. Ao usar lambdas, muitas das funções da biblioteca-padrão de Kotlin os utilizarão


36

Kotlin em Ação

como inline. Usar lambdas inline garante que nenhum objeto novo será criado, e a aplicação não sofrerá de pausas extras no GC (garbage collector, ou coletor de lixo). Agora que vimos as vantagens de Kotlin quando comparada com Java, vamos dar uma olhada na filosofia de Kotlin – as principais características que a distinguem de outras linguagens modernas voltadas para a JVM.

1.4 Filosofia de Kotlin Quando falamos de Kotlin, gostamos de dizer que é uma linguagem pragmática, concisa e segura, com foco em interoperabilidade. O que queremos dizer exatamente com cada uma dessas palavras? Vamos analisá-las individualmente.

1.4.1 Pragmática Ser pragmática significa algo simples para nós: Kotlin é uma linguagem prática, projetada para resolver problemas do mundo real. Seu design é baseado em muitos anos de experiência no mercado criando sistemas de larga escala, e suas funcionalidades foram escolhidas para atender aos casos de uso encontrados por muitos desenvolvedores de software. Além disso, desenvolvedores tanto na JetBrains quanto na comunidade usaram as versões preliminares de Kotlin durante vários anos, e seu feedback moldou a versão da linguagem que foi lançada. Isso nos dá confiança para dizer que Kotlin pode ajudar a resolver problemas em projetos do mundo real. Kotlin também não é uma linguagem de pesquisa. Não estamos tentando promover avanços no estado da arte do design de linguagens de programação nem explorar ideias inovadoras em ciência da computação. Em vez disso, sempre que possível, contamos com recursos e soluções que já apareceram em outras linguagens de programação e que se mostraram bem-sucedidos. Isso reduz a complexidade da linguagem e facilita o seu aprendizado ao permitir que você conte com conceitos conhecidos. Além do mais, Kotlin não impõe o uso de um estilo ou um paradigma particular de programação. Ao começar a estudar a linguagem, você poderá utilizar o estilo e as técnicas que lhe forem familiares em virtude de sua experiência com Java. Mais tarde você descobrirá aos poucos os recursos mais eficazes de Kotlin e aprenderá a aplicá-los em seu próprio código a fim de deixá-lo mais conciso e idiomático. Outro aspecto do pragmatismo de Kotlin é seu foco em ferramentas. Um ambiente de desenvolvimento inteligente é tão essencial para a produtividade de um


Capítulo 1 ■ Kotlin: o que é e por quê

37

desenvolvedor quanto uma boa linguagem; por isso, tratar o suporte de um IDE como uma ideia a posteriori não é uma opção. No caso de Kotlin, o plug-in para IntelliJ IDEA foi desenvolvido lada a lado com o compilador, e os recursos da linguagem sempre foram projetados com as ferramentas em mente. O suporte de IDE também desempenha um papel importante para ajudar você a descobrir os recursos de Kotlin. Em muitos casos, as ferramentas detectarão automaticamente padrões comuns de código que poderão ser substituídos por construções mais concisas, além de se oferecerem para corrigir o código para você. Ao estudar os recursos da linguagem usados nas correções automáticas, você poderá aprender a aplicá-los em seu próprio código também.

1.4.2 Concisa O fato de os desenvolvedores gastarem mais tempo lendo um código já desenvolvido do que escrevendo um código novo é de conhecimento comum. Suponha que você faça parte de uma equipe que esteja desenvolvendo um grande projeto e precise acrescentar uma nova funcionalidade ou corrigir um bug. Quais serão seus primeiros passos? Você deverá procurar a seção exata de código a ser alterada e somente então implementará uma correção. Você lerá bastante código para descobrir o que é preciso ser feito. Esse código pode ter sido escrito recentemente pelos seus colegas ou por alguém que não trabalhe mais no projeto, ou por você muito tempo atrás. Você poderá fazer as modificações necessárias somente depois que compreender o código ao seu redor. Quanto mais simples e mais conciso for o código, mais rapidamente você entenderá o que está acontecendo. É claro que um bom design e nomes expressivos desempenham um papel significativo nesse caso. Todavia a escolha da linguagem e sua concisão também são importantes. A linguagem é concisa quando sua sintaxe expressa claramente o propósito do código que você lê e não o ofusca com código boilerplate, necessário para especificar como esse propósito é implementado. Em Kotlin, nós nos empenhamos arduamente para garantir que todo código que você escrever terá um significado, e não estará presente apenas para satisfazer aos requisitos da estrutura do código. Boa parte do boilerplate Java padrão, como getters, setters e a lógica para atribuir parâmetros do construtor a campos, está implícita em Kotlin, e não deixará seu código-fonte entulhado. Outro motivo pelo qual o código pode ser desnecessariamente extenso é ter de escrever um código explícito para executar tarefas comuns, como localizar um elemento em uma coleção. Assim como muitas outras linguagens modernas, Kotlin


38

Kotlin em Ação

tem uma biblioteca-padrão rica, que permite substituir essas seções de código longas e repetitivas por chamadas de métodos de biblioteca. O suporte de Kotlin para lambdas facilita passar pequenos blocos de código para funções de biblioteca. Isso possibilita encapsular todas as partes comuns na biblioteca e manter somente a parte única, específica para uma tarefa, no código do usuário. Ao mesmo tempo, Kotlin não tenta compactar o código-fonte para o menor número de caracteres possível. Por exemplo, apesar de Kotlin aceitar sobrecarga de operadores, os usuários não podem definir seus próprios operadores. Desse modo, os desenvolvedores de bibliotecas não podem substituir os nomes dos métodos por sequências de pontuação enigmáticas. Geralmente palavras são mais fáceis de ler do que pontuações, e é mais fácil encontrar documentação sobre elas. Um código mais conciso exige menos tempo para ser escrito e, acima de tudo, menos tempo para ser lido. Isso aumenta sua produtividade e permite que você faça suas tarefas mais rapidamente.

1.4.3 Segura Em geral, quando falamos que uma linguagem de programação é segura, queremos dizer que seu design evita determinados tipos de erro em um programa. É claro que essa não é uma qualidade absoluta; nenhuma linguagem impede todos os erros possíveis. Além do mais, impedir erros em geral tem um custo. Você precisa fornecer mais informações ao compilador a respeito do funcionamento desejado para o programa para que o compilador possa então verificar se a informação está de acordo com o que o programa faz. Por causa disso, há sempre uma relação de custo-benefício entre o nível de segurança obtido e a perda de produtividade exigida para incluir mais anotações detalhadas. Com Kotlin, tentamos atingir um nível mais elevado de segurança que em Java, com um custo geral menor. Executar na JVM já proporciona muitas garantias de segurança: por exemplo, segurança de memória, prevenção contra buffer overflows (transbordamento de buffers) e outros problemas causados pelo uso incorreto de memória alocada dinamicamente. Por ser uma linguagem estaticamente tipada na JVM, Kotlin também garante a segurança de tipos em suas aplicações. Isso tem um custo menor do que em Java: você não precisa especificar todas as declarações de tipo, pois em muitos casos o compilador infere automaticamente os tipos. Kotlin também vai além, o que significa que mais erros podem ser evitados por meio de verificações em tempo de compilação, em vez de falhas em tempo de execução. Acima de tudo, Kotlin se esforça para eliminar a NullPointerException de seu programa.


Capítulo 1 ■ Kotlin: o que é e por quê

39

O sistema de tipos de Kotlin monitora valores que podem e não podem ser null e proíbe operações que possam resultar em uma NullPointerException em tempo de execução. O custo adicional necessário para isso é mínimo: marcar um tipo como nullable exige apenas um único caractere, que é um ponto de interrogação no final: val s: String? = null u val s2: String = "" v

u Pode ser null. v Não pode ser null.

Além do mais, Kotlin oferece muitas formas convenientes de lidar com dados nullable. Isso ajuda bastante na eliminação de falhas na aplicação. Outro tipo de exceção que Kotlin ajuda a evitar é a ClassCastException. Ela ocorre quando você faz cast de um objeto com um tipo sem antes verificar se ele contém o tipo correto. Em Java os desenvolvedores, muitas vezes, deixam a verificação de lado porque o nome do tipo deve ser repetido na verificação e no cast a seguir. Por outro lado, em Kotlin, a verificação e o cast são combinados em uma única operação: depois que fizer a verificação do tipo, você poderá referenciar os membros desse tipo sem nenhum cast adicional. Portanto não há motivos para ignorar a verificação nem chance de cometer um erro. Eis o modo como isso funciona: if (value is String) u println(value.toUpperCase()) v

u Verifica o tipo. v Utiliza o método do tipo.

1.4.4 Possibilita interoperabilidade Quanto à interoperabilidade, sua primeira preocupação provavelmente é: “Posso usar as bibliotecas das quais eu já me utilizo?”. Com Kotlin, a resposta é: “Sim, com certeza.” Independentemente do tipo de API que a biblioteca exija que seja usado, você poderá trabalhar com as APIs por meio de Kotlin. Você pode chamar métodos Java, ampliar classes Java e implementar interfaces, aplicar anotações Java em suas classes Kotlin, e assim por diante. De modo diferente de outras linguagens para JVM, Kotlin vai além em termos de interoperabilidade, fazendo com que chamar código Kotlin por meio de Java também não exija esforços. Nenhum truque é necessário: classes e métodos Kotlin podem ser chamados exatamente como classes e métodos Java usuais. Isso possibilita uma


40

Kotlin em Ação

flexibilidade máxima para misturar código Java e Kotlin em qualquer local de seu projeto. Ao começar a adotar Kotlin em seu projeto Java, você poderá executar o conversor de Java para Kotlin em qualquer classe única de sua base de código, e o restante do código continuará compilando e funcionando sem qualquer modificação. Isso funciona independentemente da função da classe convertida. Outra área na qual Kotlin se concentra em interoperabilidade é, no máximo, no uso de bibliotecas Java já desenvolvidas. Por exemplo, Kotlin não tem sua própria biblioteca de coleções. Ela depende totalmente das classes da biblioteca-padrão de Java, estendendo-as com funções adicionais para uso mais conveniente em Kotlin. (Veremos o mecanismo usado nesse caso com mais detalhes na seção 3.3.) Isso significa que você jamais precisará encapsular ou converter objetos quando chamar APIs Java por meio de Kotlin, ou vice-versa. Toda a riqueza de APIs oferecida por Kotlin não tem custo algum em tempo de execução. As ferramentas de Kotlin também oferecem suporte completo para projetos que usam linguagens diferentes. Uma mistura arbitrária de arquivos-fontes Java e Kotlin pode ser compilada, não importa de que modo esses arquivos dependam uns dos outros. Os recursos de IDE também funcionam entre as diferentes linguagens, permitindo: • navegar livremente entre arquivos-fontes Java e Kotlin; • depurar projetos com linguagens misturadas e percorrer códigos escritos em linguagens distintas; • refatorar seus métodos Java e ter o uso em código Kotlin corretamente atualizado, e vice-versa. Esperamos que, a essa altura, o tenhamos convencido a experimentar Kotlin. Mas como você pode começar a usá-la? Na próxima seção, discutiremos o processo de compilar e executar código Kotlin tanto da linha de comando quanto usando diferentes ferramentas.

1.5 Usando as ferramentas de Kotlin Assim como Java, Kotlin é uma linguagem compilada. Isso significa que antes de poder executar um código Kotlin, é necessário compilá-lo. Vamos discutir como o processo de compilação funciona e, em seguida, analisar as diferentes ferramentas que cuidam disso para você. Se precisar de mais informações sobre como configurar seu ambiente, por favor, consulte a seção “Tutorials” (Tutoriais) no site de Kotlin (https://kotlinlang.org/docs/tutorials).


Capítulo 1 ■ Kotlin: o que é e por quê

41

1.5.1 Compilando código Kotlin O código-fonte de Kotlin geralmente é armazenado em arquivos com extensão .kt. O compilador de Kotlin analisa o código-fonte e gera arquivos .class, exatamente como faz o compilador de Java. Os arquivos .class gerados são então empacotados e executados por meio do procedimento-padrão para o tipo de aplicação com o qual você estiver trabalhando. No caso mais simples, você pode usar o comando kotlinc para compilar seu código a partir da linha de comando e utilizar o comando java para executá-lo: kotlinc <arquivo-fonte ou diretório> -include-runtime -d <nome do jar> java -jar <nome do jar>

A Figura 1.1 mostra uma descrição simplificada do processo de construção de Kotlin. Runtime de Kotlin

*.kt

Compilador de Kotlin *.class

*.java

*.jar

Aplicação

Compilador de Java

Figura 1.1 – Processo de construção de Kotlin.

O código compilado com o compilador de Kotlin depende da biblioteca de runtime de Kotlin. Esta contém as definições das classes da própria biblioteca-padrão de Kotlin e as extensões adicionadas por Kotlin às APIs Java que são padrões. A biblioteca de runtime deve ser distribuída com sua aplicação. Na maioria dos casos da vida real, você usará um sistema de construção como Maven, Gradle ou Ant para compilar seu código. Kotlin é compatível com todos esses sistemas de construção; os detalhes serão discutidos no Apêndice A. Todos esses sistemas de construção também aceitam projetos com linguagens misturadas, que combinem Kotlin e Java na mesma base de código. Além disso, Maven e Gradle cuidam da inclusão da biblioteca de runtime de Kotlin como uma dependência de sua aplicação.


42

Kotlin em Ação

1.5.2 Plug-in para IntelliJ IDEA e Android Studio O plug-in de Kotlin para IntelliJ IDEA foi desenvolvido em paralelo com a linguagem e é o ambiente de desenvolvimento mais completo disponível para Kotlin. É maduro e estável, além de oferecer um conjunto completo de ferramentas para desenvolvimento de Kotlin. O plug-in para Kotlin está prontamente incluído no IntelliJ IDEA15 e em versões mais recentes, portanto nenhuma configuração adicional será necessária. Você pode usar o IntelliJ IDEA Community Edition, que é gratuito e de código aberto, ou o IntelliJ IDEA Ultimate. Selecione Kotlin no diálogo New Project (novo projeto) e pronto. Se estiver usando o Android Studio, você poderá instalar o plug-in para Kotlin por meio do gerenciador de plug-ins. No diálogo Settings (Configurações), selecione Plugins; em seguida, clique no botão Install JetBrains Plugin (instalar plugin da JetBrains) e selecione Kotlin na lista.

1.5.3 Shell interativo Se quiser testar rapidamente pequenos fragmentos de código Kotlin, você poderá fazer isso usando o shell interativo (o chamado REPL). No REPL, você pode digitar código Kotlin linha a linha e ver imediatamente os resultados de sua execução. Para iniciar o REPL, execute o comando kotlinc sem argumentos ou utilize o item de menu correspondente no plug-in do IntelliJ IDEA.

1.5.4 Plug-in para Eclipse Se você é usuário de Eclipse, também terá a opção de usar Kotlin em seu IDE. O plug-in de Kotlin para Eclipse oferece funcionalidades essenciais de IDE como navegação e preenchimento automático de código. Esse plug-in está disponível no Eclipse Marketplace. Para instalá-lo, selecione o item de menu Help > Eclipse Marketplace (Ajuda > Eclipse Marketplace) e procure Kotlin na lista.

1.5.5 Playground online A maneira mais fácil de testar Kotlin não exige nenhuma instalação ou configuração. Em http://try.kotl.in, você encontrará um playground online no qual poderá escrever, compilar e executar pequenos programas em Kotlin. O playground tem exemplos de código que mostram os recursos de Kotlin, incluindo todos os exemplos deste livro, assim como uma série de exercícios para conhecer Kotlin de forma interativa.


Capítulo 1 ■ Kotlin: o que é e por quê

43

1.5.6 Conversor de Java para Kotlin Estar pronto para usar uma nova linguagem é uma tarefa que sempre exige esforços. Felizmente, construímos um pequeno atalho interessante que permite agilizar o seu aprendizado e a adoção da linguagem, deixando que você conte com seu conhecimento prévio de Java. Essa ferramenta é o conversor automático de Java para Kotlin. À medida que começar a conhecer Kotlin, o conversor poderá ajudá-lo a expressar algo quando você não se lembrar da sintaxe exata. Você poderá escrever o trecho de código correspondente em Java e então colá-lo em um arquivo Kotlin, e o conversor se oferecerá automaticamente para traduzir o código para Kotlin. O resultado nem sempre será o mais idiomático possível, mas será um código funcional, e você poderá fazer progressos com sua tarefa. O conversor também é ótimo para introduzir Kotlin em um projeto Java existente. Quando precisar escrever uma nova classe, você poderá fazer isso em Kotlin desde o princípio. Contudo, se for necessário fazer alterações significativas em uma classe, talvez você queira também usar Kotlin no processo. É nesse caso que o conversor entra em cena. Converta a classe para Kotlin antes e, em seguida, adicione as alterações usando todas as vantagens de uma linguagem moderna. Usar o conversor no IntelliJ IDEA é extremamente simples. Você pode copiar um fragmento de código Java e colá-lo em um arquivo Kotlin, ou invocar a ação Convert Java File to Kotlin File (converter arquivo Java para arquivo Kotlin) se precisar converter um arquivo inteiro. O conversor está acessível no Eclipse e também online.

1.6 Resumo • Kotlin é estaticamente tipada e oferece suporte para inferência de tipos, permitindo manter a correção e o desempenho, ao mesmo tempo que deixa o código-fonte conciso. • Kotlin oferece suporte tanto para o estilo de programação orientado a objetos quanto para a programação funcional, possibilitando abstrações de nível mais alto por meio de funções de primeira classe e simplificando os testes e o desenvolvimento multithreaded com suporte para valores imutáveis. • Funciona bem para aplicações do lado do servidor, com suporte completo para todos os frameworks Java, além de oferecer novas ferramentas para tarefas comuns, como geração de HTML e persistência.


44

Kotlin em Ação

• Funciona também para Android, graças a um runtime compacto, suporte especial de compilador para APIs Android e uma biblioteca rica que disponibiliza funções apropriadas a Kotlin para tarefas comuns no desenvolvimento para Android. • É gratuita e tem código aberto, com suporte completo pelos principais IDEs e sistemas de construção. • Kotlin é pragmática, segura, concisa e permite interoperabilidade, o que significa que tem como foco o uso de soluções comprovadas para tarefas usuais, evitando erros comuns como NullPointerExceptions, oferecendo suporte para códigos compactos e fáceis de ler e possibilitando integração irrestrita com Java.


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.