Te ćwiczenia są częścią kursu Kotlin dla programistów. Skorzystaj z tego kursu, jeśli będziesz wykonywać kolejno kilka ćwiczeń z programowania. W zależności od Twojej wiedzy możesz mieć dostęp do niektórych sekcji. Ten kurs jest przeznaczony dla programistów, którzy znają język zorientowany na obiekty i chcą się dowiedzieć Kotlina.
Wprowadzenie
W tym ćwiczeniu z programowania możesz utworzyć program w Kotlinie i poznać jego funkcje, w tym wartości domyślne parametrów, filtrów, lambda i funkcji kompaktowych.
Lekcje nie obejmują jednej przykładowej aplikacji, ale mają one na celu pogłębianie wiedzy. Między innymi należy jednak pamiętać o zależności od siebie. W połączeniu wiele z przykładów wykorzystuje motyw akwariowy. A jeśli chcesz zobaczyć pełne informacje o oceanarium, zapoznaj się z kursem Kotlin Bootcamp for Programmers (Ukocity) na platformie Udacity.
Co musisz wiedzieć
- Podstawy nowoczesnego, programowanego, statycznego języka programowania
- Jak prowadzić zajęcia z wykorzystaniem klas, metod i wyjątków w co najmniej jednym języku
- Jak pracować z Kotlin&s REPL (Read-Eval-Print Loop) w IntelliJ IDEA
- Podstawowe informacje o Kotlinie, w tym typy, operatory i pętle
To ćwiczenie dla programistów, którzy znają język zorientowany na obiekty i chcą dowiedzieć się więcej o Kotlinie.
Czego się nauczysz
- Jak utworzyć program z funkcją
main()
i argumentami w IntelliJ IDEA - Jak używać wartości domyślnych i funkcji kompaktowych
- Jak stosować filtry do list
- Jak utworzyć podstawowe lambda i funkcje o wyższej kolejności
Jakie zadania wykonasz:
- Skontaktuj się z REPL, aby przetestować nowy kod.
- Pracuj z IntelliJ IDEA, aby tworzyć podstawowe programy Kotlin.
W tym zadaniu utworzysz program w Kotlin, a także poznasz funkcję main()
oraz sposób przekazywania argumentów do programu z poziomu wiersza poleceń.
Możesz zapamiętać funkcję printHello()
wpisaną w REPL w poprzednim ćwiczeniu z programowania:
fun printHello() {
println ("Hello World")
}
printHello()
⇒ Hello World
Możesz zdefiniować funkcje za pomocą słowa kluczowego fun
, a następnie nazwy funkcji. Tak jak w przypadku innych języków programowania, nawiasy ()
są argumentami funkcji (jeśli występują). Kręcone nawiasy klamrowe {}
otaczają kod funkcji. Nie ma typu zwracania, ponieważ ta funkcja nie zwraca żadnych wartości.
Krok 1. Utwórz plik Kotlin
- Otwórz IntelliJ IDEA.
- Po lewej stronie w panelu Project (Projekt) w IntelliJ IDEA jest lista plików i folderów projektu. Znajdź i kliknij prawym przyciskiem myszy folder src w sekcji Hello Kotlin. (Masz już projekt Hello Kotlin z poprzedniego ćwiczenia z programowania).
- Wybierz New > Kotlin File / Class.
- W polu Rodzaj wpisz File, a następnie nadaj plikowi nazwę Hello.
- Kliknij OK.
W folderze src jest teraz plik o nazwie Hello.kt.
Krok 2. Dodaj kod i uruchamiaj program
- Podobnie jak w przypadku innych języków funkcja Kotlin
main()
określa punkt wejścia do wykonania. Wszystkie argumenty wiersza poleceń są przekazywane jako tablica ciągów tekstowych.
Wpisz lub wklej ten kod w pliku Hello.kt:
fun main(args: Array<String>) {
println("Hello, world!")
}
Tak jak we wcześniejszej funkcji printHello()
, ta funkcja nie ma instrukcji return
. Każda funkcja w Kotlin zwraca coś, nawet jeśli nie jest wyraźnie określony. Zatem funkcja ta main()
zwraca typ kotlin.Unit
, czyli w ogóle nie nadaje żadnej wartości w Kotlin.
- Aby uruchomić program, kliknij zielony trójkąt po lewej stronie funkcji
main()
. W menu wybierz Uruchom 'HelloKt'. - IntelliJ IDEA kompiluje program i go uruchamia. Wyniki są wyświetlane w okienku dziennika u dołu, tak jak pokazano poniżej.
Krok 3. Przekaż argumenty funkcji main()
Ponieważ Twój program uruchamia się z poziomu IntelliJ IDEA, a nie z wiersza poleceń, musisz określić nieco argumenty w programie w inny sposób.
- Wybierz Run > Edit Configurations (Uruchom > Edytuj konfiguracje). Otworzy się okno Uruchamianie/debugowanie konfiguracji.
- Wpisz
Kotlin!
w polu Argumenty programu. - Kliknij OK.
Krok 4. Zmień kod, aby używać szablonu ciągu znaków
Szablon ciągu znaków wstawia zmienną lub wyrażenie do ciągu tekstowego, a $
określa, że część ciągu tekstowego będzie zmienną lub wyrażeniem. Kręcone nawiasy klamrowe {}
otaczają ramkę (jeśli występuje).
- W Hello.kt zmień komunikat powitalny, aby używać pierwszego argumentu przekazywanego do programu,
args[0]
, zamiast"world"
.
fun main(args: Array<String>) {
println("Hello, ${args[0]}")
}
- Uruchom program, a dane wyjściowe będą zawierać podany argument.
⇒ Hello, Kotlin!
W tym zadaniu dowiesz się, dlaczego niemal wszystkie elementy Kotlina mają wartość i dlaczego jest to przydatne.
W innych językach występują wyrażenia, czyli wiersze kodu, które nie mają wartości. W Kotlinie prawie wszystko jest wyrażeniem i ma wartość – nawet jeśli ma wartość kotlin.Unit
.
- W polu Hello.kt wpisz kod
main()
, aby przypisaćprintln()
do zmiennej o nazwieisUnit
i wydrukować ją. (println()
nie zwraca wartości, więc zwracakotlin.Unit
).
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
- Uruchom program. Pierwszy
println()
drukuje ciąg"This is an expression"
. Druga wartośćprintln()
drukuje wartość pierwszego wyrażeniaprintln()
, tj.kotlin.Unit
.
⇒ This is an expression kotlin.Unit
- Zadeklaruj atrybut
val
o nazwietemperature
i zainicjuj go do wartości 10. - Zadeklaruj inny
val
o nazwieisHot
i przypisz wartość zwracającą instrukcjęif
/else
doisHot
, jak pokazano w poniższym kodzie. Jest to wyrażenie, więc możesz od razu użyć wartości wyrażeniaif
.
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
- Użyj wartości wyrażenia w szablonie ciągu znaków. Dodaj kod, aby sprawdzić temperaturę, aby określić, czy ryba jest bezpieczna czy zbyt ciepła, a potem uruchom program.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.
W tym zadaniu dowiesz się więcej o funkcjach w Kotlin oraz o przydatnym wyrażeniu warunkowym when
.
Krok 1. Utwórz niektóre funkcje
W tym kroku przedstawiliśmy Ci zdobytą wiedzę i utworzyliśmy różne typy funkcji. Zawartość pliku Hello.kt możesz zastąpić nowym kodem.
- Napisz funkcję o nazwie
feedTheFish()
wywołującąrandomDay()
, aby uzyskać losowy dzień tygodnia. Użyj szablonu ciągu znaków, aby wydrukowaćfood
, którą ryba zjedzą danego dnia. Obecnie ryby jedzą to samo jedzenie codziennie.
fun feedTheFish() {
val day = randomDay()
val food = "pellets"
println ("Today is $day and the fish eat $food")
}
fun main(args: Array<String>) {
feedTheFish()
}
- Wpisz funkcję
randomDay()
, aby wybrać losowy dzień z tablicy i zwrócić.
Funkcja nextInt()
przyjmuje liczbę całkowitą, co ogranicza liczbę od Random()
do 6, by dopasować ją do tablicy week
.
fun randomDay() : String {
val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday")
return week[Random().nextInt(week.size)]
}
- Funkcje
Random()
inextInt()
są zdefiniowane wjava.util.*
. U góry pliku dodaj odpowiedni import:
import java.util.* // required import
- Uruchom program i sprawdź dane wyjściowe.
⇒ Today is Tuesday and the fish eat pellets
Krok 2. Użyj wyrażenia Kiedy
Rozszerzając kod, zmień kod tak, by wybierać różne jedzenie w różne dni, używając wyrażenia when
. Instrukcja when
jest podobna do switch
w innych językach programowania, ale when
automatycznie się kończy na końcu każdej gałęzi. Jeśli sprawdzasz wyliczenie, kod jest również pokrywany we wszystkich gałęziach.
- W Hello.kt dodaj funkcję o nazwie
fishFood()
, która przyjmuje dzień jakoString
i zwraca pokarm rybny na dzień jakoString
. Użyj strategiiwhen()
, by ryby miały codziennie określone produkty. Uruchom program kilka razy, aby sprawdzić dane wyjściowe.
fun fishFood (day : String) : String {
var food = ""
when (day) {
"Monday" -> food = "flakes"
"Tuesday" -> food = "pellets"
"Wednesday" -> food = "redworms"
"Thursday" -> food = "granules"
"Friday" -> food = "mosquitoes"
"Saturday" -> food = "lettuce"
"Sunday" -> food = "plankton"
}
return food
}
fun feedTheFish() {
val day = randomDay()
val food = fishFood(day)
println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
- Dodaj domyślną gałąź do wyrażenia
when
za pomocąelse
. Jeśli chcesz mieć pewność, że w programie używane są czasem wartości domyślne, usuń gałęzieTuesday
iSaturday
.
Ustawienie gałęzi domyślnej pozwala upewnić się, że wartośćfood
jest zwracana przed zwróceniem, więc nie jest już konieczne inicjowanie. Ponieważ kod przypisuje teraz ciąg do elementufood
tylko raz, możesz zadeklarować też wartośćfood
za pomocąval
zamiastvar
.
fun fishFood (day : String) : String {
val food : String
when (day) {
"Monday" -> food = "flakes"
"Wednesday" -> food = "redworms"
"Thursday" -> food = "granules"
"Friday" -> food = "mosquitoes"
"Sunday" -> food = "plankton"
else -> food = "nothing"
}
return food
}
- Każde wyrażenie ma jakąś wartość, dlatego możesz uściślić jego treść. Zwraca bezpośrednio wartość wyrażenia
when
i eliminuje zmiennąfood
. Wartość wyrażeniawhen
jest wartością ostatniego wyrażenia gałęzi, która spełnia warunek.
fun fishFood (day : String) : String {
return when (day) {
"Monday" -> "flakes"
"Wednesday" -> "redworms"
"Thursday" -> "granules"
"Friday" -> "mosquitoes"
"Sunday" -> "plankton"
else -> "nothing"
}
}
Ostateczna wersja programu wygląda mniej więcej tak:
import java.util.* // required import
fun randomDay() : String {
val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday")
return week[Random().nextInt(week.size)]
}
fun fishFood (day : String) : String {
return when (day) {
"Monday" -> "flakes"
"Wednesday" -> "redworms"
"Thursday" -> "granules"
"Friday" -> "mosquitoes"
"Sunday" -> "plankton"
else -> "nothing"
}
}
fun feedTheFish() {
val day = randomDay()
val food = fishFood(day)
println ("Today is $day and the fish eat $food")
}
fun main(args: Array<String>) {
feedTheFish()
}
W tym zadaniu poznasz domyślne wartości funkcji i metod. Przedstawiamy też kompaktowe funkcje, które zwiększają dokładność i czytelność kodu, a także ogranicza liczbę ścieżek kodu do testowania. Funkcje kompaktowe są nazywane funkcjami pojedynczych wyrażeń.
Krok 1. Utwórz wartość domyślną parametru
W Kotlin możesz przekazywać argumenty według nazwy parametru. Możesz też określić wartości domyślne parametrów: jeśli argument nie jest podany przez rozmówcę, zostanie użyta wartość domyślna. Później, kiedy piszesz metody (funkcje członków), oznacza to, że możesz uniknąć pisania wielu przeciążeń tej samej metody.
- W elemencie Hello.kt wpisz funkcję
swim()
z parametremString
o nazwiespeed
, który podaje szybkość ryby. Parametrspeed
ma wartość domyślną"fast"
.
fun swim(speed: String = "fast") {
println("swimming $speed")
}
- Z funkcji
main()
wywołaj funkcjęswim()
na 3 sposoby. Najpierw wywołaj funkcję, używając domyślnej. Następnie wywołaj funkcję i przekaż parametrspeed
bez nazwy, a następnie wywołaj ją, podając nazwę parametruspeed
.
swim() // uses default speed
swim("slow") // positional argument
swim(speed="turtle-like") // named parameter
⇒ swimming fast swimming slow swimming turtle-like
Krok 2. Dodaj wymagane parametry
Jeśli parametr nie ma określonej żadnej wartości domyślnej, zawsze musi być przekazywany dany argument.
- W polu Hello.kt napisz funkcję
shouldChangeWater()
, która przyjmuje 3 parametry:day
,temperature
idirty
. Funkcja zwracatrue
, jeśli woda powinna się zmienić. Dzieje się tak, gdy niedziela jest za wysoka, gdy temperatura jest zbyt wysoka lub gdy woda jest zbyt brudna. Dzień tygodnia jest wymagany, ale domyślna temperatura wynosi 22, a domyślny poziom brudu to 20.
Użyj wyrażeniawhen
bez argumentu, co w Kotlinie działa jako seria testówif/else if
.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
return when {
temperature > 30 -> true
dirty > 30 -> true
day == "Sunday" -> true
else -> false
}
}
- Zadzwoń do partnera
shouldChangeWater()
z firmyfeedTheFish()
i podaj ten dzień. Parametrday
nie ma wartości domyślnej, musisz więc podać argument. Pozostałe dwa parametryshouldChangeWater()
mają wartości domyślne, więc nie musisz dla nich argumentować.
fun feedTheFish() {
val day = randomDay()
val food = fishFood(day)
println ("Today is $day and the fish eat $food")
println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules Change water: false
Krok 3. Utwórz kompaktowe funkcje
Wyrażenie when
opisane w poprzednim kroku łączy logikę w niewielką ilość kodu. Jeśli chcesz ją nieco uchwycić lub jeśli warunki do sprawdzenia są bardziej skomplikowane, możesz użyć odpowiednich zmiennych lokalnych. Kotlin obsługuje jednak kompaktowe funkcje.
W Kotlinie często występują funkcje kompaktowe, zwane też funkcjami pojedynczych wyrażeń. Gdy funkcja zwraca wyniki pojedynczego wyrażenia, możesz określić treść funkcji po symbolu =
, pominąć nawiasy klamrowe {}
i pominąć return
.
- W Hello.kt dodaj kompaktowe funkcje, aby przetestować warunki.
fun isTooHot(temperature: Int) = temperature > 30
fun isDirty(dirty: Int) = dirty > 30
fun isSunday(day: String) = day == "Sunday"
- Zmień
shouldChangeWater()
, aby wywoływać nowe funkcje.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
return when {
isTooHot(temperature) -> true
isDirty(dirty) -> true
isSunday(day) -> true
else -> false
}
}
- Uruchom program. Dane wyjściowe funkcji
println()
z użyciemshouldChangeWater()
powinny być takie same jak przed przełączeniem na korzystanie z funkcji kompaktowych.
Wartości domyślne
Wartość domyślna parametru nie musi być wartością. Może to być inna funkcja, tak jak w tym przykładzie częściowym:
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
...
W tym zadaniu dowiesz się więcej o filtrach w Kotlinie. Filtry stanowią przydatny sposób na przejście do części listy na podstawie określonych warunków.
Krok 1. Utwórz filtr
- W Hello.kt określ listę dekoracji akwarium do najwyższego poziomu za pomocą
listOf()
. Możesz zastąpić zawartość pliku Hello.kt.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
- Utwórz nową funkcję
main()
z wierszem, aby wydrukować tylko dekoracje zaczynające się od litery 'p'. Kod warunku filtra jest nawiasami klamrowymi{}
, ait
odwołuje się do każdego elementu, ponieważ filtr się zapętla. Jeśli wyrażenie zwrócitrue
, element zostanie uwzględniony.
fun main() {
println( decorations.filter {it[0] == 'p'})
}
- Uruchom program, a w oknie Uruchom zobaczysz te dane:
⇒ [pagoda, plastic plant]
Krok 2. Porównaj filtry chętnych i leniwych
Jeśli znasz filtry w innych językach, możesz zastanawiać się, czy filtry w Kotlin są chętne czy leniwe. Czy lista wyników jest tworzona od razu czy po uzyskaniu do niej dostępu? W Kotlinu możesz to robić w dowolny sposób. Domyślnie filter
chce używać listy. Za każdym razem, gdy używasz filtra, powstaje lista.
Możesz użyć Sequence
, czyli kolekcji, która pozwala wyświetlić tylko jeden element naraz, zaczynając od początku i kończąc aż do końca. Wygodne jest to, że taki interfejs API potrzebuje leniwego filtra.
- W aplikacji Hello.kt zmień kod, aby przypisać przefiltrowaną listę do zmiennej o nazwie
eager
, a następnie ją wydrukować.
fun main() {
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
// eager, creates a new list
val eager = decorations.filter { it [0] == 'p' }
println("eager: " + eager)
- Pod tym kodem oceń filtr za pomocą filtra
Sequence
z atrybutemasSequence()
. Przypisz sekwencję do zmiennej o nazwiefiltered
i ją wydrukuj.
// lazy, will wait until asked to evaluate
val filtered = decorations.asSequence().filter { it[0] == 'p' }
println("filtered: " + filtered)
Gdy zwracasz wyniki filtra jako Sequence
, zmienna filtered
nie będzie zawierać nowej listy. Będzie zawierać Sequence
elementów listy i wiedzę o filtrze, które chcesz zastosować do tych elementów. Za każdym razem, gdy otworzysz elementy elementu Sequence
, filtr zostanie zastosowany, a wynik zostanie zwrócony.
- Wymuś ocenę sekwencji, konwertując ją na wartość
List
ztoList()
. Wydrukuj wynik.
// force evaluation of the lazy list
val newList = filtered.toList()
println("new list: " + newList)
- Uruchom program i obserwuj wyniki.
⇒ eager: [pagoda, plastic plant] filtered: kotlin.sequences.FilteringSequence@386cc1c4 new list: [pagoda, plastic plant]
Aby zobaczyć, jak działa Sequence
i leniwa ocena, użyj funkcji map()
. Funkcja map()
wykonuje proste przekształcenie każdego elementu sekwencji.
- Korzystając z tej samej listy
decorations
, wykonaj transformację z użyciemmap()
, która nie powoduje żadnych działań i zwraca tylko element, który został przekazany. Dodajprintln()
, aby pokazywać każdorazowy dostęp do elementu, i przypisz sekwencję do zmiennej o nazwielazyMap
.
val lazyMap = decorations.asSequence().map {
println("access: $it")
it
}
- Drukuj
lazyMap
, drukuj pierwszy elementlazyMap
za pomocąfirst()
i drukujlazyMap
naList
.
println("lazy: $lazyMap")
println("-----")
println("first: ${lazyMap.first()}")
println("-----")
println("all: ${lazyMap.toList()}")
- Uruchom program i zajrzyj na wyniki. Drukując
lazyMap
, drukujesz tylko odwołanie doSequence
– wewnętrzny elementprintln()
nie jest wywoływany. Drukując pierwszy element, uzyskujesz dostęp tylko do pierwszego. Konwersja parametruSequence
na wartośćList
uzyskuje dostęp do wszystkich elementów.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66 ----- access: rock first: rock ----- access: rock access: pagoda access: plastic plant access: alligator access: flowerpot all: [rock, pagoda, plastic plant, alligator, flowerpot]
- Zanim zastosujesz filtr
map
, utwórz nowy:Sequence
przy użyciu oryginalnego filtra. Wydrukuj wynik.
val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
println("access: $it")
it
}
println("-----")
println("filtered: ${ lazyMap2.toList() }")
- Uruchom program i sprawdź dodatkowe dane wyjściowe. Tak jak w przypadku pierwszego elementu, wewnętrzny element
println()
jest wywoływany tylko dla elementów, do których uzyskano dostęp.
⇒ ----- access: pagoda access: plastic plant filtered: [pagoda, plastic plant]
W tym zadaniu poznasz lambda i funkcje wyższego rzędu w Kotlinie.
Lambda
Oprócz tradycyjnych funkcji nazwanych Kotlin obsługuje także lambdy. lambda to wyrażenie tworzące funkcję, Zamiast jednak deklarować funkcję nazwaną, musisz zadeklarować funkcję, która nie ma nazwy. Jednym z praktycznych aspektów jest to, że wyrażenie lambda można teraz przekazywać jako dane. W innych językach lambdy są nazywane funkcjami anonimowymi, literakami funkcji lub podobnymi.
Funkcje o wyższej kolejności
Możesz utworzyć funkcję o wyższej kolejności, przekazując lambdę do innej funkcji. W poprzednim zadaniu utworzono funkcję o wyższym priorytecie – filter
. Należy sprawdzić następujące wyrażenie lambda do filter
jako warunku do sprawdzenia:{it[0] == 'p'}
Podobnie map
jest funkcją o wyższej kolejności, a lambda, którą do niej przekażesz, była transformacją, która została zastosowana.
Krok 1. Dowiedz się więcej o lambdach
- Podobnie jak funkcje nazwane, lambda mogą mieć parametry. W przypadku lambda parametry (i w razie potrzeby ich typy) znajdują się po lewej stronie funkcji nazywanej strzałką funkcyjną
->
. Kod do wykonania znajduje się po prawej stronie strzałki funkcji. Gdy lambda zostanie przypisana do zmiennej, możesz ją nazywać tak jak funkcję.
Użyj REPL (Tools > Kotlin > Kotlin REPL), wypróbuj ten kod:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10
W tym przykładzie lambda pobiera Int
o nazwie dirty
i zwraca wartość dirty / 2
. Ponieważ filtr usuwa brud
- Składnia Kotlin' dla typów funkcji jest ściśle powiązana ze składnią lambda. Użyj tej składni, aby jasno zadeklarować zmienną, która zawiera funkcję:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
Oto co zawiera kod:
- Utwórz zmienną o nazwie
waterFilter
. waterFilter
może być dowolną funkcją, która przyjmujeInt
i zwracaInt
.- Przypisz lambdę do:
waterFilter
. - Lambda zwraca wartość argumentu
dirty
podzieloną przez 2.
Pamiętaj, że nie musisz już określać typu argumentu lambda. Typ jest obliczany na podstawie wnioskowania typu.
Krok 2. Utwórz funkcję wyższego rzędu
Do tej pory przykłady lambda wyglądają głównie jako funkcje. Prawdziwą moc lambda wykorzystuje je do tworzenia funkcji o wyższej kolejności, gdzie argumentem jednej z nich jest inna funkcja.
- Zapisz funkcję o wyższej kolejności. Oto podstawowy przykład: funkcja przyjmująca dwa argumenty. Pierwszy argument jest liczbą całkowitą. Drugi argument to funkcja, która przyjmuje liczbę całkowitą i zwraca liczbę całkowitą. Wypróbuj w REPL.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
return operation(dirty)
}
Treść kodu wywołuje funkcję, która została przekazana jako drugi argument i przekazuje do niego pierwszy argument.
- Aby wywołać tę funkcję, podaj jej liczbę całkowitą i funkcję.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15
Przekazywana funkcja nie musi być lambdą. Może to być standardowa funkcja o nazwie . Aby określić argument jako funkcję standardową, użyj operatora ::
. Dzięki temu Kotlin wie, że przekazujesz odwołanie do funkcji jako argument, a nie próbujesz wywołać funkcję.
- Spróbuj przekazać zwykłą funkcję o nazwie do
updateDirty()
.
fun increaseDirty( start: Int ) = start + 1
println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
- Aby utworzyć plik źródłowy w Kotlin w usłudze IntelliJ IDEA, rozpocznij od projektu Kotlin.
- Aby skompilować i uruchomić program w IntelliJ IDEA, kliknij zielony trójkąt obok funkcji
main()
. Dane wyjściowe pojawią się w oknie logu poniżej. - W narzędziu IntelliJ IDEA określ argumenty wiersza poleceń, które mają zostać przekazane do funkcji
main()
w sekcji Run > Edit Configurations (Uruchamianie konfiguracji >.). - Niemal wszystko w Kotlinie ma wartość. Możesz to zrobić, aby Twój kod był bardziej zwięzły, używając wartości
if
lubwhen
jako wyrażenia lub wartości zwracanej. - Domyślne argumenty eliminują potrzebę korzystania z wielu wersji funkcji lub metody. Przykład:
fun swim(speed: String = "fast") { ... }
- Aby ułatwić czytanie kodu, można korzystać z funkcji kompaktowych lub jednowyrazowych. Przykład:
fun isTooHot(temperature: Int) = temperature > 30
- Znasz już podstawy korzystania z filtrów, które używają wyrażeń lambda. Przykład:
val beginsWithP = decorations.filter { it [0] == 'p' }
- Wyrażenie lambda to wyrażenie, które tworzy funkcję bez nazwy. Wyrażenia lambda są zdefiniowane między nawiasami klamrowymi
{}
. - W funkcji o wyższej kolejności przekazujesz funkcję, taką jak wyrażenie lambda, do innej funkcji jako dane. Przykład:
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
W tej lekcji wiele się dzieje, zwłaszcza jeśli dopiero zaczynasz korzystać z lambda. Następna lekcja dotyczy lambda i kolejnych funkcji.
Dokumentacja Kotlin
Jeśli chcesz dowiedzieć się więcej na dowolny temat dotyczący tego kursu lub nie wiesz, co zrobić, wejdź na https://kotlinlang.org.
- Szablony ciągów
- Wyrażenie
when
- Funkcje pojedynczych wyrażeń
- Funkcje i lambdy w wyższej kolejności
- Filtry
- Sekwencje
- Składnia wywołania ostatniego parametru
Samouczki Kotlin
Na stronie https://try.kotlinlang.org znajdziesz szczegółowe samouczki o nazwie Kotlin Koans, internetowe narzędzie do tłumaczenia, a także kompletny zestaw dokumentacji referencyjnej z przykładami.
Kurs Udacity
Kurs Udacity na ten temat znajdziesz na kursie Kotlin dla programistów.
IntelLIJ IDEA
Dokumentację IntelliJ IDEA znajdziesz na stronie JetBrains.
Ta sekcja zawiera listę możliwych zadań domowych dla uczniów, którzy pracują w ramach tego ćwiczenia w ramach kursu prowadzonego przez nauczyciela. To nauczyciel może wykonać te czynności:
- W razie potrzeby przypisz zadanie domowe.
- Poinformuj uczniów, jak przesyłać zadania domowe.
- Oceń projekty domowe.
Nauczyciele mogą wykorzystać te sugestie tak długo, jak chcą lub chcą, i mogą przypisać dowolne zadanie domowe.
Jeśli samodzielnie wykonujesz te ćwiczenia z programowania, możesz sprawdzić swoją wiedzę w tych zadaniach domowych.
Odpowiedz na te pytania
Pytanie 1
Funkcja contains(element: String)
zwraca ciąg true
, jeśli ciąg element
jest zawarty w ciągu znaków, który jest wywoływany. Jaki będzie wynik tego kodu?
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
println(decorations.filter {it.contains('p')})
▢ [pagoda, plastic, plant]
▢ [pagoda, plastic plant]
▢ [pagoda, plastic plant, flowerpot]
▢ [rock, alligator]
Pytanie 2
Który z parametrów w definicji funkcji jest wymagany?fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}
▢ numDecorations
▢ dirty
▢ day
▢ temperature
Pytanie 3
Możesz przekazać zwykłą funkcję nazwaną (a nie jej wywołanie) do innej funkcji. Jaką drogą increaseDirty( start: Int ) = start + 1
– updateDirty(dirty: Int, operation: (Int) -> Int)
?
▢ updateDirty(15, &increaseDirty())
▢ updateDirty(15, increaseDirty())
▢ updateDirty(15, ("increaseDirty()"))
▢ updateDirty(15, ::increaseDirty)
Przejdź do następnej lekcji:
Omówienie kursu, w tym linki do innych ćwiczeń z programowania, znajdziesz w artykule "Kotlin Bootcamp for Programmers: Witamy na kursie."