DEV Community

Rodrigo Sicarelli
Rodrigo Sicarelli

Posted on

Kotlin Koans BR: Argumentos padrão

🔗 Tarefa

Imagine que você tenha várias sobrecargas de foo() na sua linguagem favorita.

Você pode substituir todas essas sobrecargas por uma única função em Kotlin.

Altere a declaração da função foo de forma que o código que usa foo seja compilado.

Java

class SobrecargaJava { public String foo(String name, int number, boolean toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number; } public String foo(String name, int number) { return foo(name, number, false); } public String foo(String name, boolean toUpperCase) { return foo(name, 42, toUpperCase); } public String foo(String name) { return foo(name, 42); } } 
Enter fullscreen mode Exit fullscreen mode

C#

using System; class SobrecargaCSharp { public string Foo(string name, int number, bool toUpperCase) { return (toUpperCase ? name.ToUpper() : name) + number; } public string Foo(string name, int number) { return Foo(name, number, false); } public string Foo(string name, bool toUpperCase) { return Foo(name, 42, toUpperCase); } public string Foo(string name) { return Foo(name, 42); } } 
Enter fullscreen mode Exit fullscreen mode

Dart

class SobrecargaDart { String foo(String name, int number, bool toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number.toString(); } String foo(String name, int number) { return foo(name, number, false); } String foo(String name, bool toUpperCase) { return foo(name, 42, toUpperCase); } String foo(String name) { return foo(name, 42); } } 
Enter fullscreen mode Exit fullscreen mode

Go

package main import ( "fmt" "strings" ) type SobrecargaGo struct{} func (s SobrecargaGo) Foo(name string, number int, toUpperCase bool) string { if toUpperCase { return strings.ToUpper(name) + fmt.Sprintf("%d", number) } return name + fmt.Sprintf("%d", number) } func (s SobrecargaGo) FooWithNumber(name string, number int) string { return s.Foo(name, number, false) } func (s SobrecargaGo) FooWithUpperCase(name string, toUpperCase bool) string { return s.Foo(name, 42, toUpperCase) } func (s SobrecargaGo) FooWithName(name string) string { return s.Foo(name, 42, false) } 
Enter fullscreen mode Exit fullscreen mode

JavaScript

class SobrecargaJavaScript { foo(name, number, toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number; } fooWithNameAndNumber(name, number) { return this.foo(name, number, false); } fooWithNameAndUpperCase(name, toUpperCase) { return this.foo(name, 42, toUpperCase); } fooWithName(name) { return this.foo(name, 42); } } 
Enter fullscreen mode Exit fullscreen mode

PHP

foo($name, $number, false); } public function fooWithUpperCase($name, $toUpperCase) { return $this->foo($name, 42, $toUpperCase); } public function fooWithName($name) { return $this->foo($name, 42, false); } } 
Enter fullscreen mode Exit fullscreen mode

Python

class SobrecargaPython: def foo(self, name, number, to_upper_case): return (name.upper() if to_upper_case else name) + str(number) def foo_with_number(self, name, number): return self.foo(name, number, False) def foo_with_upper_case(self, name, to_upper_case): return self.foo(name, 42, to_upper_case) def foo_with_name(self, name): return self.foo(name, 42, False) 
Enter fullscreen mode Exit fullscreen mode

Swift

class SobrecargaSwift { func foo(name: String, number: Int, toUpperCase: Bool) -> String { return (toUpperCase ? name.uppercased() : name) + String(number) } func foo(name: String, number: Int) -> String { return foo(name: name, number: number, toUpperCase: false) } func foo(name: String, toUpperCase: Bool) -> String { return foo(name: name, number: 42, toUpperCase: toUpperCase) } func foo(name: String) -> String { return foo(name: name, number: 42) } } 
Enter fullscreen mode Exit fullscreen mode

TypeScript

class SobrecargaTypeScript { foo(name: string, number: number, toUpperCase: boolean): string { return (toUpperCase ? name.toUpperCase() : name) + number.toString(); } fooWithNumber(name: string, number: number): string { return this.foo(name, number, false); } fooWithUpperCase(name: string, toUpperCase: boolean): string { return this.foo(name, 42, toUpperCase); } fooWithName(name: string): string { return this.foo(name, 42); } } 
Enter fullscreen mode Exit fullscreen mode

Caso de uso

Quando se fala em [default arguments (https://kotlinlang.org/docs/functions.html#default-arguments) ou argumentos padrão, está se referindo a uma característica bem prática em Kotlin.

Ela permite que alguns argumentos sejam deixados de lado quando alguém chama uma função.

Se isso acontecer, o compilador usa esses argumentos padrão no lugar dos argumentos que foram pulados.

fun calculaDesconto(preco: Double, taxaDesconto: Double = 0.05) = preco - preco * taxaDesconto calculaDesconto(preco = 50.0) calculaDesconto(preco = 100.0, taxaDesconto = 0.10) 
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, o parâmetro taxaDesconto tem um valor padrão de 5% de desconto. Ao chamar a função calculaDesconto sem especificar a taxaDesconto, o desconto de 5% será aplicado sobre o preço.

Porém, ao passar 0.10 como argumento para o parâmetro taxaDesconto, esse será o valor utilizado, substituindo o desconto padrão de 5% para 10%.

Parâmetro x Argumento

A diferença entre parâmetro e argumento em Kotlin pode ser compreendida da seguinte forma:

  • Parâmetro: identificado dentro da definição de uma função.
  • Argumento: identificado ao invocar ou usar essa função, ou seja, fora da definição.

Imagine uma função que simula a preparação de um café:

fun prepararCafe(tipo: String) = "Preparando um café $tipo..." 
Enter fullscreen mode Exit fullscreen mode

Nesta definição, tipo é considerado um parâmetro da função.

Ao solicitar a preparação de um café:

val pedido = prepararCafe("espresso") 
Enter fullscreen mode Exit fullscreen mode

Neste contexto, "espresso" é um argumento passado para a função prepararCafe().

Vantagens

  • Menos sobrecargas: permite uma única função em vez de várias versões com diferentes argumentos.
  • Flexibilidade: é possível chamar a função com diferentes combinações de parâmetros, contanto que os argumentos obrigatórios sejam fornecidos.
  • Compatibilidade com Java: funções com argumentos padrão são compatíveis com código Java, atuando como sobrecargas.

Desvantagens

  • Complexidade do código: se usados em excesso, podem complicar a leitura e o entendimento do código.
  • Descarte no bytecode Java: No Java, argumentos padrão do Kotlin não são reconhecidos. Para contornar isso, é necessário usar a anotação @JvmOverloads

Top comments (0)