5 dicas e um bônus para deixar seu código Kotlin melhor
Tags: kotlin, jetbrains, backend, braziliandevs
Published: 2021-11-21 21:41:41

## Kotlinautas

Esse conteúdo é oferecido e distribuído pela comunidade [Kotlinautas](https://twitter.com/kotlinautas/), uma comunidade brasileira que busca oferecer conteúdo gratuito sobre a linguagem Kotlin em um espaço plural.

![capa Kotlinautas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jreawpvk6whxigcpmctf.png)

## Créditos

Esse artigo foi baseado principalmente [nesses slides](https://speakerdeck.com/antonarhipov/idiomatic-kotlin-2nd-edition) do [Anton Arhipov](https://twitter.com/antonarhipov/).

## O quê é Kotlin Ideomático?

Kotlin Ideomático é uma maneira de escrever Kotlin tentando seguir os melhores padrões e funcionalidades da linguagem. Buscando tornar o código mais legível e menor.

Há uma [página oficial](https://kotlinlang.org/docs/idioms.html) da documentação do Kotlin apenas para listar diversas formas ideomáticas de fazer coisas. Caso saiba um pouco de inglês, é interessante ler esse documento. Neste artigo vamos abordar apenas algumas formas ideomáticas de se usar Kotlin, mas nessa página há uma quantidade bem maior.

## Criando funções sem classes

Muitas pessoas que migram do Java para o Kotlin, continuam com o costume de criar uma classe toda vez que precisarem criar uma ou mais funções, mas isso não é necessário no Kotlin, pois podemos criar funções sem precisar de uma classe associada, dessa maneira:

```kotlin
fun main(){
  olaMundo()
}

fun olaMundo(){
  println("Olá Mundo!")
}
```

- Criamos uma função `olaMundo`, que mostra o texto `Olá Mundo!` na tela;
- Chamamos essa função dentro da `main`;

## Extensões

Sabe aquelas funções `.toInt`, `.equals`,etc. que podemos usar em tipos do Kotlin? Podemos adicionar novas funções completamente feitas por nós á esses tipos, usando as extensões.

Vamos supor que você quer criar uma função chamada `ÉNumero` que irá checar se uma *string* é um número ou não. Essa função seria executada da seguinte forma:

```kotlin
"isso não é um número".ÉNumero
"10".ÉNumero
```

Isso pode ser feito criando a função `ÉNumero` dessa maneira:

```kotlin
fun String.ÉNumero() = all { it.isDigit() }
```

- Passamos o tipo, no caso `String`, seguido de um `.` e o nome da função, que no caso é `ÉNumero`;
- A função `all` irá testar se todos os caracteres do texto conseguem passar de uma certa condição, que no caso é se esse caractere é um dígito usando a função `isDigit`;

Após isso, podemos utilizar essa função em qualquer lugar do nosso código:

```kotlin
fun main(){
	println("10".ÉNumero())
	println("abracadabra".ÉNumero())
}
```

## Funções de escopo

Funções de escopo são funções axuliares que executam um código com o contexto de um objeto. Isso significa que essas funções criam um escopo temporário, onde poderemos usar todas as propriedades de um objeto sem precisar informar esse projeto. Caso tenha tido alguma confusão, vamos ver na prática.

Vamos supor que temos uma classe `Estrela`, com as propriedades `nome`, `diâmetro`, dessa maneira:

```kotlin
data class Estrela(
	var nome: String = "",
	var diâmetro: Int = 0,
	var numeroDePlanetas: Int = 0,
)
```

Podemos criar uma variável que guarde uma instância, e mudar as propriedades dessa variável. Dessa maneira:

```kotlin
val sol = Estrela()
sol.nome = "sol"
sol.diâmetro = 1392700
sol.numeroDePlanetas = 8
```

Esse código irá funcionar, mas não está sendo ideomático, pois estamos repetindo a variável `sol` diversas vezes. Podemos escrever esse código de uma maneira mais bonita como no exemplo abaixo:

```kotlin
	val sol = Estrela().apply {
		nome = "sol"
		diâmetro = 1392700
		numeroDePlanetas = 8
	}
```

- Usamos a função `apply` do Kotlin, que irá receber um objeto (no caso uma instância de `Estrela`) e irá fazer alterações com esse objeto em seu contexto. No caso, definindo valores de propriedades.

Dessa maneira, nosso código estará mais consiso, legível, e ideomático.

Há outras funções de escopo, essas outras funções podem ser vistas [Nessa página da documentação do Kotlin](https://kotlinlang.org/docs/scope-functions.html)

## Argumentos Padrão e Argumentos Nomeados

Vamos supor que temos a seguinte função:

```
fun saudações(nome: String, momento: String){
	println("Olá $nome! $momento")
}
```

Essa função está recebendo um `nome`, como `Pedro` ou `Maria`, e momento recebe uma saudação do dia, como `boa tarde` ou `boa noite`.

Mas vamos pensar: Na maior parte das vezes, damos `bom dia` para as pessoas, e menos vezes damos `boa tarde` ou `boa noite`.

Logo, podemos mudar a função e fazer que esse `momento` tenha um valor padrão usando um `=` depois de seu tipo.

```
fun saudações(nome: String, momento: String = "Bom Dia!"){
	println("Olá $nome! $momento")
}
```

E além, e se essa pessoa não quiser passar seu nome? Podemos deixar `Pessoa Anônima` como valor padrão, da mesma forma que dizemos com `momento`. Dessa maneira:

```
fun saudações(nome: String = "Pessoa Anônima", momento: String = "Bom Dia!"){
	println("Olá $nome! $momento")
}
```

Com isso, podemos chamar essa função `saudações` de algumas formas:

```kotlin
fun main(){
	saudações()
	saudações("Maria")
	saudações("Pedro", "Boa Noite!")
}
```

Resultado:

```
Olá Pessoa Anônima! Bom Dia!
Olá Maria! Bom Dia!
Olá Pedro! Boa Noite!
```

> E se eu quiser deixar o argumento `nome` padrão, e mudar só a mensagem?

Isso pode ser feito nomeando o argumento `momento` na chamada, dessa maneira:

```kotlin
fun main(){
	saudações(momento = "Boa Tarde!")
}
```

Resultado:

```
Olá Pessoa Anônima! Boa Tarde!
```

## Funções de única expressão

Vamos supor que temos uma função `testarTemperatura` que recebe uma temperatura em *String* e diz se é possível tomar uma bebida nessa temperatura ou não:

```kotlin
fun testarTemperatura(temperatura: String): String{
	when(temperatura){
		"quente" -> return "Quente demais para beber"
		"frio" ->  return "Temperatura boa para beber"
		else -> return "Preciso deixar um pouco na geladeira"
	}
}
```

Essa função tem apenas uma única expressão, um único comando em seu corpo. logo, podemos simplificar essa função, removendo seu corpo e seu retorno e adicionando um `=` seguido pela expressão.

Dessa maneira, nossa função ficará assim:

```kotlin
fun testarTemperatura(temperatura: String) = when(temperatura){
		"quente" -> "Quente demais para beber"
		"frio" ->  "Temperatura boa para beber"
		else -> "Preciso deixar um pouco na geladeira"
}
```

Dessa maneira, nossa função ficará bem menor, consisa e legível, essas são as [funções de única expressão](https://kotlinlang.org/docs/functions.html#single-expression-functions), a mesma coisa que fizemos com o `when` pode ser feita com `if`, `try`,etc.

## Operador Elvis

Vamos supor que temos uma classe `Cachorro`, essa toda instância de `Cachorro` tem um nome, raça (que pode ser `null` caso esse cachorro seja vira-lata) e uma propriedade `educado`. Dessa maneira:

```kotlin
class Cachorro(
	val nome: String,
	val raça: String?,
	val educado: Boolean,
)
```

Junto com essa classe, temos uma função `apresentarCachorro` que irá receber uma instância dessa classe `Cachorro`, e caso esse cachorro seja de raça, e a sua raça não seja `null`, o seu nome e raça serão mostrados na tela jutn ocom uma mensagem. Normalmente, fariamos dessa maneira:

```kotlin
fun apresentarCachorro(cachorro: Cachorro){
	if (cachorro.raça == null){
		return
	}

	val raça = cachorro.raça
	val nome = cachorro.nome

	if (cachorro.educado){
		println("Au Au Au, meu nome é $nome e sou da raça $raça, Au Au Au")
	}
}
```

Esse código pode ser melhorado. Podemos remover o primeiro if que testa se a raça do cachorro é null ou não. Podemos colocar esse teste direto na definição da variável `raça`, dessa maneira:

```kotlin
fun apresentarCachorro(cachorro: Cachorro){
	val raça = cachorro.raça ?: return
	val nome = cachorro.nome

	if (cachorro.educado){
		println("Au Au Au, meu nome é $nome e sou da raça $raça, Au Au Au")
	}
}
```

No código acima, usamos o operador Elvis (`?:`), onde se o valor da esquerda for `null`, o código da direita será executado. No caso, é o `return` que irá fechar a função sem nenhum conteúdo no retorno.

## Finalização

Nesse artigo, você aprendeu 6 dicas de como deixar o seu código Kotlin mais ideomático, consiso e legível. Busque aplicar os conceitos mostrados nesse artigo (e em outros sobre Kotlin Ideomático que podem existir) em seus projetos, pois assim seu código ficará bem melhor.

Muito obrigada por ler ❤️🏳️‍⚧️ e me segue nas redes, é tudo [@lissatransborda](https://twitter.com/lissatransborda) 👀