O Kotlin 1.4-M3 foi lançado: mudanças na biblioteca padrão

Postado em por luizdibella

O Kotlin 1.4-M3 foi lançado: mudanças na biblioteca padrão

Hoje temos o prazer de apresentar a última versão de pré-visualização do Kotlin 1.4 – 1.4-M3. Neste post vamos guiá-lo através das mudanças à biblioteca padrão do Kotlin que fazem parte desta pré-visualização. Outros componentes também estão sendo atualizados na versão M3. Eles serão abordados em breve em outro post com a versão release candidate (1.4-RC), que finalizará o escopo do Kotlin 1.4.

As mudanças na biblioteca padrão na versão 1.4-M3 incluem:

Você pode encontrar a lista completa de mudanças no log de alterações. Como sempre, somos muito gratos aos nossos colaboradores externos.

Apreciaremos bastante se você puder experimentar a pré-visualização e compartilhar suas impressões.

Artefatos da biblioteca padrão agora incluem descritores module-info

A partir do Java 9, você pode modularizar sua aplicação graças ao projeto Jigsaw. A ferramenta jlink permite que você gere uma imagem Java runtime contendo apenas os módulos da plataforma que são necessários para sua aplicação. Antes já era possível usar o jlink com artefatos da biblioteca padrão Kotlin, mas era preciso usar artefatos separados – apenas os que tinham o classificador "modular" – e todo o processo de configuração não era simples. A impossibilidade de incluir descritores de módulos nos artefatos principais foi causada por problemas nas ferramentas para Android, que já foram corrigidos.

O Kotlin 1.4 acrescenta as informações sobre módulos de module-info.java aos artefatos default da biblioteca padrão, para que você possa usá-los com o jlink com facilidade. No Android, certifique-se de estar usando o plugin Android Gradle versão 3.2 ou superior, que é capaz de processar corretamente jars contendo module-info.

Suporte a fun interface na biblioteca padrão

O Kotlin 1.4 suporta conversões SAM para classes Kotlin. Você pode marcar uma interface que tenha um único método abstrato como uma fun interface e depois passar um lambda como argumento quando essa interface for esperada como parâmetro. Na biblioteca padrão, as seguintes interfaces são agora declaradas como fun interface:

  • Comparator
  • ReadOnlyProperty
  • PropertyDelegateProvider (foi introduzida em 1.4-M2)

Você pode usar um construtor SAM que recebe um lambda como parâmetro para criar uma instância. O código resultante é muito mais simples:

<img class="alignnone size-full wp-image-55452" src="https://blog.jetbrains.com/wp-content/uploads/2020/07/fun_interface-1.png" onmouseover="this.src=’https://blog.jetbrains.com/wp-content/uploads/2020/07/fun_interface.gif‘;"
onmouseout="this.src=’https://blog.jetbrains.com/wp-content/uploads/2020/07/fun_interface-1.png‘;" alt="" />

Operações de coleções

  • Uma nova função sumOf recebe uma função seletora e retorna uma soma de seus valores sobre todos os elementos de uma coleção. É muito parecida com as funções sumBy e sumByDouble que já existem. A principal diferença é que a nova função sumOf recebe seletores com vários tipos de retorno, permitindo que você lide com somas de diferentes tipos da mesma forma. Ou seja, sumOf produz somas dos tipos Int, Long, Double, UInt, ULong. Na JVM também estão disponíveis os tipos BigInteger e BigDecimal.
  • As funções min e max foram renomeadas para minOrNull e maxOrNull. Desde sua introdução na versão 1.0, as funções min e max têm retornado null em coleções vazias. Isto contradiz a convenção de nomenclatura usada em toda a API de coleções do Kotlin: funções sem o sufixo *OrNull lançam uma exceção se a coleção receptora estiver vazia. Se você ainda quiser receber um null, você deve usar a versão *OrNull da função, por exemplo, firstOrNull.
    Portanto, decidimos gradualmente alterar o comportamento de min e max. Na versão 1.4-M3, estamos acrescentando minOrNull e maxOrNull como sinônimos de min e max e iniciando o ciclo de deprecação para min e max para que elas sejam reintroduzidas com tipos de retorno que não sejam null.
  • Introduzimos as funções minOf e maxOf que retornam o valor mínimo ou máximo da função seletora fornecida sobre os itens da coleção. Estas funções resolvem a situação na qual era necessário escrever map { selector }.max()!! ou maxBy { selector }!!.selector (ou min e minBy).

    Para manter a consistência com a API existente, também acrescentamos minOfWith e maxOfWith, que recebem um Comparator como argumento.
    Todas essas novas funções seguem a convenção non-null que descrevemos acima: elas lançam exceções em coleções vazias e possuem versões *OrNull que retornam null neste caso.

  • Novas sobrecargas para flatMap e flatMapTo permitem que você use transformações com tipos de retorno que não combinam com o tipo do receptor, ou seja:

    • transformações para Sequence em Iterable, Array e Map
    • transformações para Iterable em Sequence
  • Uma nova função flatMapIndexed foi acrescentada como uma contrapartida para flatMap. Como você talvez já saiba, Indexed no nome de uma função que processa coleções significa que a operação aplicada recebe o índice do elemento como parâmetro.

Anotação @Throws comum

Embora Kotlin não tenha exceções checadas, ele usa a anotação code>@Throws para garantir a interoperabilidade com linguagens que as possuem, tais como Java e Swift. Antes, havia anotações separadas com este nome para a JVM (kotlin.jvm.Throws) e Native (kotlin.native.Throws). A partir da versão 1.4-M3, a anotação code>@Throws está disponível como parte da biblioteca comum diretamente no pacote kotlin (kotlin.Throws), o que permite que você a utilize no código comum.

@Throws em funções suspensas no Swift e Objective-C

Na versão 1.4-M1 anunciamos mudanças no tratamento de exceções na interop Objective-C/Swift: agora NSError é lançada apenas para exceções que são instâncias de classes especificadas como parâmetros de uma anotação code>@Throws (ou suas subclasses). Na versão 1.4-M2 introduzimos suporte básico para as funções de suspensão do Kotlin no Swift e Objective-C. Na versão 1.4-M3 há pequenas mudanças no comportamento das funções de suspensão anotadas com code>@Throws:

  • Se você tiver uma suspend fun anotada com @Throws, você precisa especificar CancellationException::class como parâmetro da anotação @Throws. Caso contrário, você terá um erro de compilação.
  • Se não houver anotação @Throws em uma suspend fun, ela irá usar implicitamente @Throws(CancellationException::class) quando for chamada pelo Swift.

Igualdade em arrays de ponto-flutuante

Muitos de vocês conhecem estas funções de extensão práticas para tipos de container – contains, indexOf e lastIndexOf. Algum tempo atrás, descobrimos que seu comportamento em arrays de ponto-flutuante (FloatArray e DoubleArray) pode ser controverso e pode parecer incorreto.
Para ser mais específico, eles usam o padrão
IEEE 754 para aritmética de ponto-flutuante. Este padrão define as seguintes regras de igualdade para casos especiais:

  • NaN não é igual a NaN
  • -0.0 é igual a 0.0

Tais regras podem levar a resultados inesperados, por exemplo:

Adicionalmente, tal comportamento é inconsistente com a forma como essas mesmas funções operam em listas, porque elas usam igualdade de ordem total:

Na versão 1.4-M3 começamos o ciclo de deprecação para as funções de extensão contains, indexOf e lastIndexOf de FloatArray e DoubleArray. Ao tentar utilizá-las, você receberá avisos com instruções para substituir os usos dessas funções.
Em lançamentos futuros aumentaremos o nível de deprecação para ERROR e removeremos essas funções da API pública.

Conversão de KType para Java Type

No Kotlin 1.3.40 acrescentamos uma prática função typeOf à biblioteca padrão. Esta função retorna uma representação em tempo de execução do tipo reificado T como instância de KType. Porém, em muitos casos de uso práticos, você precisa trabalhar com objetos java.lang.reflect.Type da API Java reflection em vez de usar KType. Já era possível realizar a conversão necessária, mas para isto era necessário usar a dependência kotlin-reflect inteira. Agora atualizamos a biblioteca padrão com uma forma de converter um KType em um Type Java – uma propriedade de extensão KType.javaType que retorna um Type Java:

Note que, até o momento, o Type Java obtido não se comporta da forma correta em alguns casos especiais (como em parâmetros de tipo anotados ou variância no local da declaração), portanto KType.javaType continua experimental. Você pode encontrar mais detalhes sobre os casos não suportados neste issue.

Compatibilidade

Observe que o Kotlin 1.4 não tem compatibilidade retroativa com a versão 1.3 em alguns casos especiais. Todos esses casos foram cuidadosamente revisados pelo comitê da linguagem e serão listados no "guia de compatibilidade" (semelhante a este). Por enquanto, você pode encontrar esta lista no YouTrack.

Notas de pré-lançamento

Observe que as garantias de compatibilidade retroativa não abrangem versões de pré-lançamento. Os recursos e a API poderão mudar em lançamentos subsequentes. Quando chegarmos a uma RC final, todos os binários produzidos pelas versões de pré-lançamento serão proibidos pelo compilador, e você precisará recompilar tudo o que foi compilado pelo 1.4‑Mx.

Como experimentar os últimos recursos

Como sempre, você pode experimentar o Kotlin online em play.kotl.in.

No IntelliJ IDEA e Android Studio você pode atualizar o Kotlin Plugin para a versão 1.4-M3. Veja como fazer isso.

Se quiser trabalhar em projetos existentes que foram criados antes de instalar a versão de prévia, será necessário configurar sua compilação para a versão de prévia no Gradle ou Maven.

Você pode baixar o compilador de linha de comando da página do lançamento no GitHub.

Você pode usar as seguintes versões das bibliotecas publicadas junto com este lançamento:

Os detalhes do lançamento e a lista de bibliotecas compatíveis também estão disponíveis aqui.

Compartilhe suas impressões

Somos gratos por todos os relatos de bugs que você enviou para nosso rastreador de issues e faremos o melhor possível para corrigir todos os issues mais importantes antes do lançamento final.

Você também está convidado a participar do canal #eap no nosso Kotlin Slack (obtenha um convite aqui). Neste canal você pode fazer perguntas, participar de discussões e receber notificações dos novos builds de pré-visualização.

Mãos à obra com o Kotlin!

Contribuições externas

Gostaríamos de agradecer a todos os nossos contribuintes externos cujos pull requests foram incluídos neste lançamento: