Jason. Cała informatyka w jednym miejscu!

Czy już macie pojęcie, że słowo kluczowe "fun" w języku Kotlin pozwala na programowanie funkcji? Język i w tym przypadku poszedł innymi śladami niż jego poprzednik i określa swoją własną składnię. Poznajcie same najpotrzebniejsze detale, abyście mogli zaraz po przeczytaniu wdrożyć nową wiedzę do projektu. Gwarantuję, że będziecie mieli z tego niezły "fun"!

"FUN" W JĘZYKU KOTLIN. "ZABAWNE" PODEJŚCIE DO FUNKCJI

Dobra, żarty na bok. Słowo kluczowe "fun" umożliwia definiowanie funkcji jako skrót od "function". Mieliście okazję już na samym początku ujrzeć funkcje w akcji podczas prezentowania pierwszego programu w Kotlinie. Przypomnę się:

fun main(args: Array<String>) {
	
}

Postawmy "main" z języka Java obok tego:

public static void main(String[] args) {
	
}

Od razu rzuca się w oczy kilka widocznych różnic.

  • Brak modyfikatora dostępu
    • Żaden "fun" w języku Kotlin nie potrzebuje nakładania "public", "private" czy jeszcze jakiegoś innego modyfikatora. To JEST dostępne, aczkolwiek traktowane jak sprawa poboczna kiedy chcemy zaprogramować nieszablonowe podejście. Język nie wymaga, abyśmy musieli koniecznie wstawiać modyfikator dostępu do każdej funkcji jak leci.
  • Żadnego "static"
    • Java nakazuje traktowania funkcji "main" jako statycznej, gdyż inaczej wirtualna maszyna nie byłaby w stanie jej odnaleźć. Tylko, że...obok Kotlinowego "main" tego nie ma. Co więcej, tego słowa nie ma W OGÓLE w całym języku Kotlin! Czyli mamy kolejne słowo kluczowe obcięte z definicji. Coraz prościej!
  • Proceduralny zapis zamiast obiektowego

FUNKCJE OD SAMEGO POCZĄTKU

Jeszcze raz prześledźmy wszystko od początku. Za tworzenie nowej funkcji odpowiada słowo "fun" w języku Kotlin. Po nim dodajemy natychmiast nazwę jaka będzie służyła za etykietę celem identyfikacji. Następnie otwieramy parę nawiasów okrągłych, bez względu na to czy będą wymagać jakichś parametrów, czy nie.

PRAWIDŁOWY ZAPIS PARAMETRÓW FORMALNYCH

Skoro o parametrach mowa, podajemy je inaczej niż w Javie. Java "każe" pisać tak:

(int n, String s, boolean b)

Kotlin za to w ten sposób:

(n: Int, s: String, b: Boolean)

Została odwrócona kolejność. Parametry należące do "fun" w języku Kotlin podaje się odwrotnie. Najpierw jest nazwa zmiennej, a po dwukropku typ dużą literą. W tym przypadku MUSIMY za każdym razem podać typ z jednego prostego powodu: kompilator zaopatrzony w dedukcję może się "domyślić" typu tylko po jego wartości. Ale na etapie definicji nagłówka żadnych wartości nie ma, bo podamy je dopiero przy wywołaniu! To tak samo jak przy samym zadeklarowaniu zmiennej przy pomocy słowa "var" bez podawania wartości na starcie:

var x: Int

Dlatego każdy parametr funkcji musi mieć z góry ustalony typ RĘCZNIE.

"VOID"? JAKI "VOID"?

Państwo drodzy! Kotlin nie zna takiego słowa kluczowego jak "void"! Jak dobrze Państwo wiedzą z języka Java, oznacza to jedynie wykonywanie czynności przez funkcję, czyli brak zwrotu wartości. Kotlin raz kolejny obrał swoją drogę i tu zasady są inne. Po pierwsze, "void" w Kotlinie został zastąpiony słowem "Unit". Po drugie, "Unit" to domyślny typ funkcji którego nie trzeba jawnie pisać. Każda funkcja nieposiadająca samodzielnie zdefiniowanego typu jest uważana za "Unit", czyli za funkcję niezwracającą żadnej wartości. "main" również to dotyczy, dlatego też to:

fun main(args: Array<String>) {
	
}

zostaje poddane obróbce przed uruchomieniem i w rzeczywistości wygląda tak:

fun main(args: Array<String>): Unit {
	
}

Zwróćcie uwagę nie na słowo, ale gdzie się ono znajduje. Miejsce na definiowanie typu zwracanej wartości umieszczone jest na samym końcu! Po zamknięciu nawiasu, wstawiacie dwukropek i nazwę. Tym samym dajecie sobie już odpowiedź na pytanie jak można zmienić typ zwracanej wartości.

Typ "Unit" funkcji w języku Kotlin

Domyślnym typem każdej funkcji w języku Kotlin jest "Unit", odpowiednik słowa "void" oznaczającego procedurę (funkcję niezwracającą żadnej wartości).

ZWRACANIE WARTOŚCI PRZEZ FUNKCJĘ

Oto co zrobić, aby wpłynąć na typ zwracanej wartości przez funkcję. Przypuśćmy, że chcemy napisać funkcję zwracającą sześcian podanej liczby całkowitej. Tu macie kod w Javie:

public int cube(int n) {
	return n*n*n;
}

Kiedy "fun" w języku Kotlin ma zwracać wartość, musicie zagwarantować dwa elementy. Raz, to pożądany przez Was typ wartości:

fun cube(n: Int): Int

a dwa, słowo kluczowe "return". Kompilator za Chiny nie puści kodu do obiegu bez słowa "return", kiedy funkcja ma zwracać wartość. Chociaż to słowo pozostało takie same:

fun cube(n: Int): Int {
	return n*n*n
}

Tyle! Co do możliwości "typowania" typów, nic nie ulega zmianie. To może być "Int", "String", "Array<Boolean>" czy cokolwiek innego. Tylko zapomnijcie o zwracaniu "null" (chyba, że korzystacie z typu akceptującego wartości puste)! Inny typ niż podany również nie przejdzie, chyba że przez konwersję. Pamiętacie? Zapewnienie bezpieczeństwa!

FUNKCJA JEDNOWYRAŻENIOWA

A na deser, nowość języka Kotlin! Funkcja składająca się wyłącznie z jednej jedynej linijki kodu! Nazywana "funkcją jednowyrażeniową" została zaprojektowana z myślą o definiowaniu króciutkich funkcji dla prostych nieskomplikowanych instrukcji. Można napisać, że przypomina nieco wyrażenie lambda, a to z powodu składni jaką oferuje "fun" w języku Kotlin w wersji "light". Weźmy nawet tę samą funkcję "cube" z przykładu powyżej i przeanalizujmy jej wygląd:

fun cube(n: Int) = n*n*n

Nie dajecie wiary, że to przejdzie? To zbudujcie sobie projekt z tym fragmentem i uruchomcie. Wypunktujmy sobie różnice jakie rzucają się w oczy.

  • Brak jawnego określenia typu zwracanej wartości
    • Widzicie, że nie ma śladu po typie zwracanej wartości? Nie występuje fragment ": Int" zaraz po zamykającym nawiasie okrągłym. W tej sytuacji pominięcie jest dozwolone, ponieważ kompilator jest w stanie wywnioskować jaki typ ma zostać wstawiony na podstawie typu parametru wykorzystanego do wyrażenia ("Int").
  • Znak przypisania zamiast pary klamerek
    • To jest druga charakterystyczna cecha po jakiej możemy poznać funkcję jednowyrażeniową. Nie ma konieczności definiowania dla niej "pola do manewrów" ze względu na występowanie pojedynczej instrukcji, zatem nawiasy klamrowe zamienia się na znak przypisania (=).
  • Brak słowa kluczowego "return"
    • I ostatnia różnica dzięki której rozpoznacie funkcję jednowyrażeniową w try miga. Stąd porównanie do wyrażenia lambda, gdyż w nim także można pominąć słowo kluczowe "return", o ile kompilator domyśli się o co Wam chodzi. Ponieważ chcemy zwrócić sześcian podanego parametru, podając samo wyrażenie po znaku przypisania kompilator już będzie wiedział, że chodzi nam po głowie zwrócenie wartości w postaci "n" do potęgi trzeciej.

Pamiętajcie, że każdy "fun" w języku Kotlin zwracający wartość można "upchnąć" w funkcję jednowyrażeniową, o ile kończy się tylko na jednej instrukcji. Zatem jeśli funkcja wykonuje już dwie instrukcje (na przykład zmienna lokalna + instrukcja "return"), to musi już przyjąć tradycyjną formę z klamerkami. Możecie wstawić także wyrażenie warunkowe i żeby funkcja zwracała konkretną wartość w zależności od podanego warunku. Umiejętne posługiwanie się tą funkcjonalnością, sprawi że Wasz kod nie tylko będzie wykonywał sumiennie swoje zadanie, ale także będzie schludny, czysty i będzie się świecił w edytorze jak nie napiszę co.

Funkcja jednowyrażeniowa w języku Kotlin

Funkcja jednowyrażeniowa stanowi kolejny sposób na uproszczenie kodu sprowadzając zapis do prostego wyrażenia lambda, w którym także można uniknąć jawnego definiowania typu oraz treści ograniczonej klamerkami.

WYWOŁANIE

Ostatnim podpunktem będzie odpowiedź na pytanie "jak wywołać metodę?". Nie wprowadzono żadnych modyfikacji w kwestii samego korzystania z metody. Obowiązują te same zasady. Nazwa, nawiasy okrągłe, parametry wewnątrz nawiasów (musi się zgadzać liczba oraz typy!) i średnik na końcu instrukcji którego Kotlin akurat nie potrzebuje. Jeżeli funkcja ma zwracać wartość, zwykle przypisuje się wywołanie do zmiennej, o tak:

val c = cube(5)

choć nie jest to żadnym wymaganiem. Równie dobrze można zostawić samo wywołanie i kod też zostanie przyjęty, natomiast nie przyniesie żadnego wpływu na przebieg działania.


Mając nadzieję, że o niczym nie zapomniałem wspomnieć, uznaję temat za zamknięty i życzę, aby dobrze służył podczas opanowywania materiału.

PODOBNE ARTYKUŁY