Kotlin with fun! Funções

Thais Aquino
luizalabs

--

Um aperitivo de código para começar… Qual o esforço de fazer um Hello World no Kotlin? Quase nada:

fun main(args: Array<String>) {
println("Hello World!")
}

ou mais enxuto ainda…

fun main(args: Array<String>) = println("Hello World!")

No Kotlin as funções são declaradas usando a palavra reservada fun, parâmetros (caso tenha) e um retorno. Toda função tem um retorno, mesmo que não especificado, como no exemplo anterior. Quando o retorno não é informado é considerado retorno Unit, equivalente ao Void do Java. A seguir um exemplo de função que tem retorno especificado:

fun soma(a: Int, b: Int): Int {
return a + b
}

Após informar o nome da função e os parâmetros colocar “: Tipo” que no nosso caso retorna Int.

Uma observação sobre o primeiro exemplo: a linha que imprime Hello World usamos apenas println ao invés de System.out.println, isso é possível devido a wrappers em torno de funções da standard library do Java para termos uma sintaxe mais limpa.

Top-level function e properties

Top-level function são funções colocadas diretamente em um arquivo .kt sem estar aninhada a uma classe. Elas resultam em métodos estáticos no byte code.

Top-level properties também colocadas diretamente em um arquivo .kt sem classe resultam em propriedades estáticas após a compilação para o byte code.

Block body e expression body

A função soma tem um block body porque tem o corpo definido por chaves, podemos escrevê-la com um expression body para ficar mais curta ainda, sem a necessidade da palavra reservada return:

fun soma(a: Int, b: Int): Int = a + b

E se não estiver contente, quiser deixar mais curta ainda, pode omitir o tipo de retorno da função que será inferido pelo contexto do retorno devido ao mecanismo de type inference tornando a função single-line:

fun soma(a: Int, b: Int) = a + b

Omitir o tipo só é possível em funções com expression body!

Named Parameters

fun main(args: Array<String>) {
println(concat("Je ", "veux ", " chocolat"))
// Je veux chocolat
}

fun concat(a: String, b: String, c: String) = a.plus(b).plus(c)

A função concat que criei recebe três parâmetros do tipo String. E fiz a chamada dela da forma que estamos habituados a ver em Java. Agora usando named parameters ficaria assim:

concat(a = "Je ", b = "veux ", c = " chocolat")

Da forma acima fica explícito quais parâmetros estamos atribuindo os valores. Nem todos os parâmetros precisam ser nomeados, mas se nomear o primeiro parâmetro os seguintes também devem ser nomeados.

Usando named parameters é possível informar os parâmetros em ordem diferente da declarada na função, como a seguir:

concat(c = "chocolat ", a = "Je ", b = "veux ")

Default Parameters

As vezes criamos funções em que não necessariamente precisamos que todos os parâmetros sejam informados, atribuindo algum valor padrão a eles. No Kotlin podemos usar os default parameters. Como no exemplo, setamos valores default para os parâmetros b e c:

fun concat(a: String, b: String = " default b", c: String=" default c") = a.plus(b).plus(c)

Na chamada, podemos informar apenas o parâmetro a que não tem valor padrão:

concat(a = "teste")

Esse recurso é muito útil para evitar boilerplate com diversas variantes sobrecarregadas da mesma função.

--

--

Thais Aquino
luizalabs

Senior Software Engineer (Flutter | React Native | Android | iOS)