W Kotlin funkcje są deklarowane w sposób bardzo zwięzły, co jest jedną z mocnych stron języka. Historycznie w Java funkcje są ściśle związane z klasami (metody), nie obsługują parametrów nazwanych ani domyślnych, co często wymaga tworzenia przeciążeń metod. W Kotlin funkcje mogą być deklarowane na najwyższym poziomie (top-level), a ich parametry są znacznie bardziej elastyczne.
Problem w Java: dla różnych kombinacji argumentów często trzeba tworzyć osobne przeciążenia. Prowadzi to do nadmiaru kodu i utrudnia utrzymanie.
Rozwiązanie w Kotlin:
Przykład kodu:
fun greet(name: String = "User", greeting: String = "Hello") { println("$greeting, $name!") } greet() // Hello, User! greet("Alex") // Hello, Alex! greet(greeting = "Hi", name = "Olga") // Hi, Olga!
Kluczowe cechy:
Czy argumenty domyślne są częścią sygnatury funkcji w bajtkodzie?
Nie, Kotlin kompiluje osobne synthetic overload-metody, aby zapewnić zgodność z Java, ale sygnatura funkcji nie zmienia się na poziomie JVM.
Co się stanie, jeśli zamieni się kolejność argumentów nazwanych i pozycyjnych?
Argumenty pozycyjne muszą być podawane przed nazwanymi, w przeciwnym razie wystąpi błąd kompilacji.
Przykład nieprawidłowego użycia:
greet(greeting = "Hey", "Ivan") // Błąd kompilacji
Czy można deklarować funkcje poza klasami w Java tak samo jak w Kotlin?
Nie, w Java każda funkcja musi być metodą jakiejś klasy. W Kotlin dopuszczalne są funkcje top-level — co sprawia, że kod jest czystszy i bardziej testowalny.
Negatywny przypadek
W dużym projekcie Android deweloper zaimplementował metody API klienta z 5-6 argumentami pozycyjnymi i przeciążeniami, co prowadziło do częstych błędów przy wywołaniach i dużych zduplikowanych blokach kodu.
Zalety:
Wady:
Pozytywny przypadek
Użycie funkcji z parametrami domyślnymi i nazwanymi dało kompaktową sygnaturę, usunęło potrzebę przeciążeń, ryzyko błędów i poprawiło wygodę utrzymania API.
Zalety:
Wady: