Kotlin je moderný programovací jazyk. Vytvorila ho firma JetBrains. Vysokú podporu má od Google a preto je využitý v platforme Android. Je však natoľko univerzálny a má takú podporu knižníc, že je využitý i pre multiplatformové nasadenie pre iOS, web frontend (JavaScript), Linux, Windows a aj servery (Ktor), kde beží pod JVM (Java, napríklad Apache Tomcat).
Vyznačuje sa stručnosťou (oproti Java). Je možné v jednom projekte kombinovať Java aj Kotlin. Bezpečnosť voči null ukazateľom je vyriešená (null safety). Lambda funkcie výrzane uľahčujú písanie a stručnosť kódu. Coroutins zjednodušujú prácu s asynchronnými procesmi (vlákna) a preberanie odpovedí z nich.
var : variable (dynamický obsah)
val : value (konštantná hodnota)
| Byte | -128..127, 8 bit |
| Short | -32768..32767, 16 bit |
| Int | -2147483648..2147483647, 32 bit |
| Long | -263 .. 263 - 1, 64 bit |
| Float | +-1.4 * 10^−45 .. +-3.4 * 1038, presnosť: 7 čísel |
| Double | +-5.0 * 10^−324 .. +-1.7 * 10308, presnosť: 15 .. 16 čísel |
| Char | 16 bit |
| Boolean | 8 bit |
| String |
==, >, <, <=, >=, !=, !
if ()
if() else
if() else if()
when(var) {…} \\ when(val) {val → {…} else → {…}}
when() else
&&, ||
for (i in m..n)
while ()
repeat(n) {}
it : aktuálny riadok cyklu
fun myFc() = sequence<Int> { for(i in m..n) { yield(i) // yield() vracia hodnotu, zväčša do .forEach{} volajúcej fc } }
var myValue:<ValueType>? : povolenie null
anyCommand(myValue!!) : vypnutie kontroly
myValue?.let { anyCommand } : bezpečné volanie
anyCommand(myValue?.anyMethod ?: defaultValue) : bezpečné volanie s elvis operátorom
var myArray = arrayOf<ValueType>()
val myArray: Array<ValueType>(val1, … val_n)
var myList: List<ValueType> = listOf() … myList += newValue … myList -= selectedList
Konverzie
val myArray: Array<CharSequence> = myArrayList.toTypedArray() // ArrayLit to Array
časté funkcie:
Matematické funkcie
import kotlin.math.*
class MyClass { … }
[modifikatorPristupu] [menoMetody] ([parametre]) : [navratovyTyp]
val myValue = MyClass()
class MyClass(myValue: ValueType) { val myVal: ValueType init { this.myVal = myValue } }
class MyClass(val myValue: ValueType) { constructor() : this(defaultValue) }
class MyClass(private var myValue) { // getters and setters fun getMyValue(): ValueType { // getter return myValue } fun setMyValue(myVal valueType) { // setter myValue = myVal } }
class MyClass(myValue: ValueType) { // private set var myValue = myValue private set }
class MyClass(myValue: ValueType) { // backing properties var myValue = myValue private set get() { return expressionResult } }
class MyClass(myValue: ValueType) { // set value var myValue = myValue [private] set(value) { foo = value } }
open calss MyParentClass(protected val myOirginalVale: ValueType) { … }
class MyChildClass(myOirginalVale: ValueType, private var myOtherValue: ValueType) : MyParentClass(myOirginalVale) { … init { this.myOtherValue = myOtherValue } }
stejné meno metódy v dcérskej triede ako v materskej, ale iná funkcia
class MyClass() { … companion object { val myValue = anyValue private var myLocalValue = anyValue fun myMethod(…): returnValueType { … } } }
statická trieda - objekt, bude dostupné všade aj bez inštancie
object MyObject { init { … } val/var/fun … }
interface MyInterface { fun anyFunction() }
class MyClass: MyInterface { override fun anyFunction() { … } }
val myClass: MyInterface = MyClass()
interface NextInterface { fun nextFunction() }
klik na žiarovku → Implement members
class NextClass: MyInterface, NextInterface { override fun anyFunction() { … } override fun nextFunction() { … } }
val nextClass = NextClass()
val myClass: MyInterface = NextClass()
val myClass: MyInterface = NextClass()
myClass.anyFunction()
myClass.nextFunction()
(myClass as NextClass).nextFunction()
- if (myClass is MyClass) { … } - (myClass as MyClass).anyFunction()
enum class MyEnum { MyStatus1 { override fun toString(): String { return “anyString1” } }, MyStatus2 { override fun toString(): String { return “anyString2” } } }
enum class MyEnum(private val text: String) { // ! (private val text: String) je konštruktor ktorý vytvára v triede inštanciu MyStatus1(“anyString1”), MyStatus2(“anyString2”); override fun toString(): String { return text } }
private var myEnum: Set<MyEnum> init { myEnum(MyEnum.MyStatus1, MyEnum.MyStatus2) } myEnum += MyEnum.MyStatusN myEnum -= MyEnum.MyStatusN if (myEnum.contains(MyStatus1)) { … }
class MyClass { companion object { // static, use: myClass.MY_CONST_VALUE const val MY_CONST_VALUE = anyValue // const val je nastavená pri kompilácii, val môže meniť hodnotu napríklad z konštruktoru } }
if (myClass_instance1 == myClass_instance2) { … }
class MyClass(val myVal: typeVal) Clonable { … } // Clonable je marker-interface - clone() je protected a definuje sa v triede: class MyClass(val myVal: typeVal) Clonable { public override fun clone(): Any { return super.clone() } }
public fun clone(): Any { val obj1 = super.clone() as Obj1 obj1.instX = obj1.instX.clone() as Obj2 return obj1 }
data class Obj1(val val1: String, …)
data class Obj1(val val1: String, …) { constructor(val val1: String) : this(val val1: String, “other string parameter”, …) }
fun fun1(…, Ivararg vars1: ValType): ValType { for (item in vars1) { … } return result }
class Obj1 { class Obj2 { } }
fun fun1(par1: ValType, par2: ValType = anyValue) { ... }
funX(par2 = anyValue, par1 = anyValue)
fun fun1(): ValType = anyValue + anyValue // príklad pre sčítanie
Odporúča sa použiť LcalDateTime z Java 8, nie Date, alebo Calendar, alebo Joda-Time
import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime import java.time.Month
val datumCas = LocalDateTime.of(2016, Month.APRIL, 15, 3, 15) // dátum a čas val datum = LocalDate.of(2016, Month.APRIL, 15) // len dátum val cas = LocalTime.of(3, 15, 10) // len čas val datumCas = LocalDateTime.now() val datum = LocalDate.now() val cas = LocalTime.now()
import java.time.format.DateTimeFormatter import java.time.format.FormatStyle
val dateTime = LocalDateTime.now() println(dateTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM))) println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL))) println(dateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT))) println(dateTime.format(DateTimeFormatter.ofPattern("d.M.y H:m:ss")))
https://www.itnetwork.cz/kotlin/oop/datum-a-cas-v-kotlin-uprava-a-intervaly
toLocalDate() toLocalTime()
val zacatek = LocalDate.of(1939, 9, 1) val datumCas = zacatek.atStartOfDay() val datumCas2 = zacatek.atTime(0, 0)
minusDays(), minusHours(), minusMinutes(), minusMonths(), minusNanos(), minusSeconds(), minusWeeks(), minusYears() plusDays(), plusHours(), plusMinutes(), plusMonths(), plusNanos(), plusSeconds(), plusWeeks(), plusYears()
import java.time.Period
práca s intervalom - minus(), plus() ⇒ Period a Duration Duraton je len interval bez súvisu na kalendár Pariod akceptuje prechody na letný/zimný čas
import java.time.temporal.ChronoUnit
pre prácu s intervalom (pre Duration)
získanie intervalu medzi dvoma dátumami
compareTo(), isAfter(), isBefore(), isEqual(), isLeapYear(), isSupported(ChronoUnit.X)
Instant : nanosekundy od 1.1.1970 - Instant.now() #thisDteIsBeginOfLinuxEpoch ZoneId : špecifikácia zóny - ZonedDateTime.now(ZoneId.of("America/New_York")) .ofEpochSecond() : linux timestamp = sekundy od 1.1.1970 : LocalDate.ofEpochSecond() toEpochSecond(), toEpochDay() : prevod na sekundy
po ukončení bloku measureTimeMillis {} je vrátený čas jeho trvania v milisekundách:
val runningTime = measureTimeMillis { dataOperation() } println(runningTime)
Tu sú uvedené linky na Kotlin portfolio vzdelávánie od JetBrains a Google.
Kotlin Docs - Základy (kotlinlang.org)
Kotlin Multiplatform - Začíname s KMP (kotlinlang.org)
Compose Multiplatform - Tvorba UI (jetbrains.com)
Ktor - Dokumentácia Ktor (ktor.io)
Android developers developers (developer.android.com)