O livro "Kotlin. Programação para profissionais "

imagem Oi, habrozhiteli! O livro de Josh Skin e David Greenhall é baseado no popular curso Kotlin Essentials do Big Nerd Ranch. Exemplos vívidos e úteis, explicações claras dos principais conceitos e APIs fundamentais não apenas introduzem a linguagem Kotlin, mas também ensinam a usar seus recursos de forma eficaz, além de permitir que você domine o ambiente de desenvolvimento JetBrains IntelliJ IDEA.

Não importa se você é um desenvolvedor experiente que deseja ir além do Java ou está aprendendo a primeira linguagem de programação. Josh e David irão guiá-lo desde os princípios básicos até o uso prolongado do Kotlin, para que você possa criar aplicativos confiáveis ​​e eficientes.


Para quem é este livro?


Nós (os autores) escrevemos este livro para desenvolvedores de diferentes calibres: desenvolvedores Android experientes que não possuem recursos Java, desenvolvedores de código de servidor interessados ​​nos recursos Kotlin e também para iniciantes que decidem aprender uma linguagem compilada eficaz.

Este livro pode lhe interessar no suporte ao Android, mas não se limita à programação no Kotlin para Android. Além disso, neste livro, apenas um capítulo - capítulo 21 - discute as técnicas de programação Kotlin para Android. No entanto, se você estiver interessado no tópico do uso do Kotlin para desenvolver aplicativos Android, este livro apresentará as técnicas básicas que simplificarão o processo de criação de aplicativos Android no Kotlin.

Embora o Kotlin tenha sido influenciado por outros idiomas, você não precisa saber como eles foram projetados para funcionar com sucesso com o Kotlin. Periodicamente, compararemos o código Java e Kotlin. Se você tem experiência em desenvolvimento em Java, isso o ajudará a entender o relacionamento entre as duas linguagens. E se você não tiver essa experiência, exemplos de solução dos mesmos problemas em outro idioma o ajudarão a entender as idéias que influenciaram a formação do Kotlin.

Como usar este livro


Este livro não é uma referência. Nosso objetivo é o aprendizado consistente da língua Kotlin. Você trabalhará com projetos e aprenderá o idioma no processo. Para maior efeito, recomendamos que você experimente todos os exemplos de código ao ler o livro. Trabalhar com exemplos o ajudará a desenvolver a memória "muscular" e fornecerá idéias que lhe permitem passar de um capítulo para outro.

Cada próximo capítulo é baseado no anterior. Recomendamos não pular capítulos. Mesmo que você tenha estudado o tópico enquanto trabalha com outros idiomas, sugerimos que você leia pelo menos aqui: muitas coisas são implementadas de maneira diferente no Kotlin. Começaremos com tópicos introdutórios, como variáveis ​​e listas, e depois passaremos para as técnicas de programação orientada a objetos e funcional para fazer você entender o que faz do Kotlin uma ferramenta tão poderosa. No final do livro, você passará de um iniciante a um desenvolvedor avançado no Kotlin.

Queremos acrescentar que você não deve se apressar: desenvolva, use a documentação do Kotlin no link: kotlinlang.org/docs/reference , onde existem respostas para muitas perguntas que surgem durante os experimentos.

Trecho. Extensões


As extensões permitem adicionar funcionalidade a um tipo sem alterar explicitamente a declaração de tipo. Use extensões com tipos personalizados e com os quais você não tem controle, como Lista, String e outros tipos da biblioteca padrão Kotlin.
Extensões são uma alternativa à herança. Eles são adequados para adicionar funcionalidade a um tipo se a definição de classe não estiver disponível para você ou se a classe não tiver um modificador aberto que permita criar subclasses.

A biblioteca padrão Kotlin geralmente usa extensões. Por exemplo, as funções padrão que você aprendeu no capítulo 9 são extensões declaradas e, neste capítulo, você verá alguns exemplos de suas declarações.

Neste capítulo, primeiro trabalharemos em um projeto Sandbox e, em seguida, aplicaremos esse conhecimento para otimizar o código NyetHack. Para começar, abra o projeto Sandbox e crie um novo arquivo chamado Extensions.kt.

Declaração da função de extensão


Sua primeira extensão permite adicionar algum grau de entusiasmo ao String. Declare-o em Extensions.kt.

Listagem 18.1. Adicionando uma extensão para o tipo String (Extensions.kt)

fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) 

As funções de extensão são declaradas da mesma maneira que outras funções, mas com uma diferença: ao definir uma função de extensão, você também especifica um tipo conhecido como tipo de recebimento ao qual o ramal adiciona recursos. (Lembre-se do Capítulo 9, onde chamamos tipos extensíveis de “receptores”.) Para a função addEnthusiasm, um tipo de String de aceitação é especificado.

O corpo da função addEnthusiasm é apenas uma expressão que retorna uma sequência: o conteúdo deste e 1 ou mais pontos de exclamação, dependendo do valor do argumento da quantidade (1 é o valor padrão). A palavra-chave this refere-se à instância do objeto de destino para o qual a extensão é chamada (nesse caso, a instância String).
Agora você pode chamar a função addEnthusiasm para qualquer instância de String. Tente uma nova função de extensão declarando uma linha na função principal e chamando a função de extensão addEnthusiasm para exibir o resultado.

Listagem 18.2. Chamando um novo ramal para uma instância do objeto receptor String (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun main(args: Array<String>) { println("Madrigal has left the building".addEnthusiasm()) } 

Execute Extensions.kt e verifique se a função de extensão adiciona um ponto de exclamação à string, conforme pretendido.

É possível subclassificar String para adicionar esse recurso às instâncias String? No IntelliJ, observe o código-fonte da declaração String pressionando a tecla Shift duas vezes para abrir a caixa de diálogo Search Everywhere e digite "String.kt" na caixa de pesquisa. Você verá esta declaração de classe:

 public class String : Comparable<String>, CharSequence { ... } 

Como a palavra-chave aberta não está na declaração da classe String, você não pode subclassificar String para adicionar novos recursos por herança. Como mencionado anteriormente, as extensões são uma boa opção se você deseja adicionar funcionalidade a uma classe que não pode gerenciar ou não pode usar para criar uma subclasse.

Declaração de extensão da superclasse


As extensões não dependem da herança, mas podem ser combinadas com a herança para aumentar o escopo. Tente isso em Extensions.kt: declare uma extensão para o tipo Any com o nome easyPrint. Como a extensão é declarada para Qualquer, estará disponível para todos os tipos. Principalmente, substitua a chamada de função println pela chamada de extensão easyPrint para String.

Listagem 18.3. Qualquer extensão (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint() = println(this) fun main(args: Array<String>) { println("Madrigal has left the building".addEnthusiasm()).easyPrint() } 

Execute Extensions.kt e verifique se a saída não foi alterada.

Desde que você adicionou a extensão para o tipo Qualquer, ela também está disponível para subtipos. Adicione uma chamada de extensão para Int.

Listagem 18.4. O easyPrint está disponível para todos os subtipos (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint() = println(this) fun main(args: Array<String>) { "Madrigal has left the building".addEnthusiasm().easyPrint() 42.easyPrint() } 

Funções de extensão genéricas


Mas e se você quiser imprimir a linha “Madrigal saiu do prédio” antes e depois do addEnthusiasm?

Para fazer isso, adicione a capacidade de chamar a cadeia à função easyPrint. Você já viu cadeias de chamadas de função: as funções podem participar de uma cadeia se retornar um objeto receptor ou outro objeto para o qual as funções subseqüentes possam ser chamadas.
Atualize o easyPrint para ligar o encadeamento.

Listagem 18.5. Alterar easyPrint para chamar encadeamento (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint()= println(this): Any { println(this) return this } ... 

Agora tente chamar a função easyPrint duas vezes: antes e depois do addEnthusiasm.

Listagem 18.6. Ligue para a easyPrint duas vezes (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint(): Any { println(this) return this } fun main(args: Array<String>) { "Madrigal has left the building".easyPrint().addEnthusiasm().easyPrint() 42.easyPrint() } 

O código não foi compilado. A primeira chamada do easyPrint foi permitida, mas o addEnthusiasm não. Veja as informações de tipo para entender por que isso acontece: clique no easyPrint e pressione Control-Shift-P (Ctrl-P) e, na lista de extensões que aparece, selecione o primeiro: ("Madrigal saiu do prédio .easyPrint ()") (Fig. 18.1).

A função easyPrint retorna a string para a qual foi chamada, mas usa o tipo Qualquer para representá-la. addEnthusiasm está disponível apenas para String, portanto, não pode ser chamado no valor retornado pelo easyPrint.

imagem

Para resolver esse problema, você pode fazer uma extensão generalizada. Atualize a função de extensão easyPrint e use o tipo genérico como aceitador em vez de Qualquer.

Listagem 18.7. Generalizando o easyPrint (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun <T> AnyT.easyPrint(): AnyT { println(this) return this } ... 

Agora, quando a extensão usa o parâmetro do tipo generalizado T como receptor e retorna T em vez de Qualquer, informações sobre o tipo específico do objeto receptor são transmitidas pela cadeia (Fig. 18.2).

imagem

Tente executar o Extensions.kt novamente. Desta vez, a linha será impressa duas vezes:

 Madrigal has left the building Madrigal has left the building! 42 

Sua nova função de extensão generalizada funciona com qualquer tipo e também processa informações sobre ela. As extensões que usam tipos genéricos permitem gravar funções que podem funcionar com uma grande variedade de tipos em um programa.

Extensões para tipos genéricos também estão disponíveis na biblioteca padrão Kotlin. Por exemplo, veja a declaração da função let:

 public inline fun <T, R> T.let(block: (T) -> R): R { return block(this) } 

let é declarado como uma função de extensão genérica, que permite trabalhar com todos os tipos. É preciso um lambda que pega o objeto receptor como argumento (T) e retorna o valor de algum novo tipo R.

Preste atenção à palavra-chave inline, que aprendemos no Capítulo 5. O mesmo conselho que fornecemos anteriormente se aplica aqui: declarar uma função de extensão como incorporada, se ela aceitar um lambda, reduz os custos de memória.

»Mais informações sobre o livro podem ser encontradas no site do editor
» Conteúdo
» Trecho

Desconto de 25% no cupom para Khabrozhitel - Kotlin
Após o pagamento da versão impressa do livro, um livro eletrônico é enviado por e-mail.

Source: https://habr.com/ru/post/pt464177/


All Articles