Kotlin
Kotlin is a modern, statically-typed programming language that runs on the Java Virtual Machine (JVM). It was developed by JetBrains and first released in 2011.
All examples are based on Kotlin 1.8.0.
Resources:
How to start
A simple and fast way to get started with Kotlin is to use an IDE like IntelliJ IDEA.
//main.kt
fun main() {
println("Hello, world")
}
Topics
- Variables
- Primitive Types
- Operators
- Strings
- Null Safety
- Operator Overloading
- Collections
- Conditional Statements
- Loops
- Functions
- Classes
- Nested and Inner Classes
- Object Declarations
- Data Classes
- Sealed Classes
- Enum Classes
- Companion Objects
- Interfaces
- Class Inheritance
- Visibility Modifiers
- Funcional Interfaces (SAM)
- Coroutines - basic concepts
- Coroutines - suspending functions
- Coroutines - scopes
- Error Handling
- Let Expression
- Pair and Triple
- Destructuring declarations
- Delegation
- Keywords
Variables
//var: mutable variable
var x = 10
//val: immutable variable
val y = 10
//typed variable
val z: Int = 10
//nullable variable
val a: Int? = null
Primitive Types
val a: String = "Hello"
val b: Int = 10
val c: Double = 3.14
val d: Boolean = true
val f: Byte = 100
val g: Short = 1000
val h: Long = 100000
val i: Float = 10.0F
val j: Char = 'a'
val k: CharSequence = "Hello"
Any type: is a variable of any type
val any: Any = "Hello"
any = 10
any = true
Operators
//Arithmetic Operators
val a = 10 + 20
val b = 10 - 20
val c = 10 * 20
val d = 10 / 20
val e = 10 % 20
//Comparison Operators
val a = 10 == 20
val b = 10 != 20
val c = 10 > 20
val d = 10 < 20
val e = 10 >= 20
val f = 10 <= 20
//Logical Operators
val a = true && false
val b = true || false
//Assignment Operators
var a = 10
a += 20
a -= 20
a *= 20
a /= 20
a %= 20
//Conditional Operators
val a = 10
a ?: 20
//Range Operators
val a = 10..20
for (i in a) { println(i)}
//Type test
if (a is Int) { println("a is Int") }
if (a is String) { println("a is String") }
//Bitwise Operators
val a = 10 and 20
val b = 10 or 20
val c = 10 xor 20
val d = 10 shl 20
val e = 10 shr 20
val f = 10 ushr 20
//Elvis operator
val a = null
var b = a ?: "default"
Strings
//single line string
var a = "Hello world"
//multiline string
var b = """
Hello
world
"""
//string interpolation
var c = "Hello $a"
//string template
fun message(): String { return "Hello World!" }
println("message: ${message()}")
Null Safety
Null safety is a feature in Kotlin that helps prevent null pointer exceptions. It allows you to declare variables as nullable, and then handle the case where the variable is null.
//null-nullable variable
val a: String? = null
//null nullable variable
val b: String = a ?: "default"
//null-aware operator (safe call operator)
val c = a?.length
//null assertion operator
val d = a!!.length
//check for null in conditions
val e = if (a != null) { a.length } else { 0 }
//elvis operator with nullable receiver
val l = b?.length ?: 0
//safe casts
val f: String = a as? Int
Operator Overloading
Operator overloading allows you to define custom behavior for specific operators. In Kotlin, you can define operator overloading for arithmetic operators, comparison operators, and more.
data class Point(val x: Int, val y: Int)
operator fun Point.plus(other: Point): Point {
return Point(this.x + other.x, this.y + other.y)
}
val point = Point(1, 2)
val other = Point(3, 4)
fun main(args: Array<String>) {
println(point + other) //Point(x=4, y=6)
}
Collections
List: is a simple collection of objects. There is two types of list: mutable and immutable.
val list = listOf("a", "b", "c")
val typedList: List<Int> = listOf(1, 2, 3)
var mutableList = mutableListOf("a", "b", "c")
//some methods
mutableList.add("d")
mutableList.remove("b")
mutableList.clear()
mutableList.addAll(list)
mutableList.first()
mutableList.last()
mutableList.forEach { println(it) }
Set: is an unordered collection of unique elements. There are two types of sets: mutable and immutable.
var set = setOf(1, 2, 3, 4, 5)
var typedSet: Set<Int> = setOf(1, 2, 3, 4, 5)
var mutableSet: MutableSet<Int> = mutableSetOf(1, 2, 3, 4, 5)
//some methods
mutableSet.add(6)
mutableSet.remove(3)
mutableSet.clear()
mutableSet.contains(3)
mutableSet.size
mutableSet.isEmpty()
mutableSet.forEach { println(it) }
Map: is a collection of key-value pairs. There are two types of map: immutable and mutable
val map = mapOf<String, String>()
val typedMap: Map<String, String> = mapOf(
"key1" to "value1",
"key2" to "value2"
)
var mutableMap = mutableMapOf<String, String>(
"key1" to "value1",
"key2" to "value2"
)
//some methods
mutableMap.put("key3", "value3")
mutableMap.putAll(typedMap)
mutableMap.remove("key1")
mutableMap.clear()
mutableMap.isEmpty()
mutableMap.containsKey("key1")
mutableMap.containsValue("value1")
mutableMap.forEach { println("key: $it.key, value: $it.value") }
Array: Arrays are collections of fixed size that contain elements of the same type. Kotlin supports both mutable and immutable arrays.
val array = arrayOf("a", "b", "c")
println(array)
//some methods
array.size
array.isEmpty()
array.contains("a")
array.contains("d")
array.indexOf("a")
array.lastIndexOf("a")
Sequence: Sequences are special types of collections that lazily compute their elements. They are useful for performing operations on large or infinite collections without eagerly computing all elements at once.
var sequence = sequenceOf(1, 2, 3, 5)
//some methods
sequence.count()
sequence.sum()
sequence.max()
sequence.min()
sequence.average()
sequence.toList()
Range: Ranges are not collections in the traditional sense, but they represent a sequence of values between a start and an end, inclusive or exclusive.
val range = 1..5
println(range)
//some methods
range.count()
range.sum()
range.max()
range.min()
range.average()
range.toList()
Collection Type | Mutable Implementation | Immutable Implementation |
---|---|---|
List | MutableList | List |
Set | MutableSet | Set |
Map | MutableMap | Map |
Array | Array | N/A |
Sequence | N/A | N/A |
Range | N/A | N/A |
Conditional Statements
val x = 10
// if statement
if (x > 5) { println("x is greater than 5") }
else{ println("x is less than or equal to 5") }
//inline if
println(if (x > 5) "x is greater than 5" else "x is less than or equal to 5")
//when expression
when (x) {
0 -> println("x is 0")
1 -> println("x is 1")
2 -> println("x is 2")
3 -> println("x is 3")
4 -> println("x is 4")
5 -> println("x is 5")
else -> println("x is greater than 5")
}
//when expression with return
val y = when (x) {
0 -> "x is 0"
1 -> "x is 1"
2 -> "x is 2"
3 -> "x is 3"
4 -> "x is 4"
5 -> "x is 5"
else -> "x is greater than 5"
}
println(y)
Loops
//for loop
for (i in 1..5) {
println(i)
}
//while loop
var i = 1
while (i <= 5) {
println(i)
i++
}
//do-while loop
var i = 1
do {
println(i)
i++
} while (i <= 5)
//range loop
for (i in 1..5) {
println(i)
}
//range loop with step
for (i in 1..5 step 2) {
println(i)
}
//rage loop with step and reverse
for (i in 6 downTo 0 step 2) {
println(i)
}
Functions
//function with no parameters
fun sayHello() {
println("Hello")
}
//function with parameters
fun sayHello(name: String) {
println("Hello, $name")
}
//function with multiple parameters
fun sayHello(name: String, age: Int) {
println("Hello, $name, you are $age years old")
}
//function with return type
fun add(a: Int, b: Int): Int {
return a + b
}
//function with default parameter
fun sayHello(name: String = "World") {
println("Hello, $name")
}
//infix function:
//is a simple way to extends a class with a new method
infix fun Int.add(i: Int) = this + i
var a: Int = 10
println(a.add(5))
//lambda function:
//is a function that can be passed as an argument to another function
val add = fun(a: Int, b: Int): Int { return a + b }
println(add(5, 10))
//function overloading
fun add(a: Int, b: Int): Int { return a + b }
fun add(a: String, b: String): Int { return a.toInt() + b.toInt() }
Calling functions with multiple parameters
When a function have multiple parameters, the last parameter can be called with {}
.
fun calc(x: Int, y: Int, action: (Int, Int) -> Int): Int
{
return action(x, y)
}
//calling
var a = calc(5, 10) { a, b -> a + b }
var b = calc(5, 10) { a, b -> a * b }
var c = calc(5, 10) { a, b -> a - b }
var d = calc(5, 10) { a, b -> a / b }
println("a = $a")
println("b = $b")
println("c = $c")
println("d = $d")
Classes
Classes can contain:
- Constructors and initializer blocks
- Functions
- Properties
- Nested and inner classes
- Object declarations
Constructors:
//primary constructor
class Person(val name: String, val age: Int)
class Person(name: String, age: Int) {
var name: String = name
var age: Int = age
}
//secondary constructor
class Person {
var name: String
var age: Int
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}
//initializer block
class Person {
var name: String = "John"
var age: Int = 25
init {
println("Person name: $name")
println("Person age: $age")
}
}
//initializer block
class Person(private val name: String, private var age: Int) {
init {
println("Person initialized with name: $name and age: $age")
}
}
Properties, Fields, Getters and Setters:
// default getter and setter are generated
class Person {
var name: String = ""
}
//custom getter and setter
class Person {
var age: Int = 0
get() = field
set(value) {
if (value < 0)
throw IllegalArgumentException("Age cannot be negative")
}
}
//backing property
class User {
private var _email: String = ""
var email: String
get() = _email
set(value) {
_email = value
println("Email changed to $value")
}
}
val user = User()
user.email = "email@gmail.com"
Nested and inner classes
In Kotlin, an inner class is a class declared within another class. Inner classes have a special relationship with the outer class, allowing them to access the members of the outer class, including private members. Hereβs an explanation of inner classes in Kotlin:
//outer class members
class Outer {
// Inner class members
inner class Inner {
}
}
//access to outer class members
class Store(private var name: String) {
inner class Car(private var color: String) {
fun info(){
println("Car color $color from store $name")
}
}
}
val store = Store("My Store")
val car = store.Car("Red")
car.info()
//qualifier access
//this@Outer: refers to the outer class
class Outer {
private val outerProperty: Int = 10
inner class Inner {
fun accessOuterProperty() {
println("Outer property value: ${this@Outer.outerProperty}")
}
}
}
Object declarations
In Kotlin, object declarations provide a convenient way to define singleton objects, which are objects that have only one instance throughout the entire application.
object Car {
private var make = "ford"
private var model = "mustang"
private var color = "red"
private var year = 2020
fun printInfo() {
println("make: $make, model: $model, color: $color, year: $year")
}
}
Car.printInfo()
Anonymous objects
In Kotlin, anonymous objects are instances of anonymous classes. These classes are defined directly within an expression, without a separate class declaration.
An anonymous class is created using the object
keyword followed by the declaration of the class or interface it implements, as well as its members.
open class Person(val name: String, val age: Int)
var hero = object : Person("Superman", 50){
override fun toString(): String {
return "I am $name and I am $age years old"
}
}
println(hero) // I am Superman and I am 50 years old
if (hero is Person) { println("I am a person")}
Data Classes
In Kotlin, data classes are a special kind of class designed to hold data and provide some automatic functionality out of the box. They simplify the process of creating classes specifically for storing data.
data class Person(val name: String, val age: Int)
val p = Person("John", 25)
val p2 = p.copy(name = "Jane", age = 26)
Sealed Classes
Sealed classes in Kotlin are a powerful feature that allow you to represent restricted class hierarchies. When you have a known set of subclasses, a sealed class can enforce that all subclasses are defined in the same file or within the same module. This is particularly useful for modeling state machines, result types, or other structures where the possible types are known and finite.
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val data: String) : Result()
data object Loading : Result()
}
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println(result.data)
is Result.Error -> println(result.data)
is Result.Loading -> println("Loading...")
}
}
fun main() {
val success = Result.Success("Success message")
val error = Result.Error("Error message")
val loading = Result.Loading
handleResult(success)
handleResult(error)
handleResult(loading)
}
Enum Classes
Enum classes in Kotlin are a way to define a set of named values. They are similar to Javaβs enum classes, but with some additional features and syntax.
enum class Color(val name: String) {
RED("Red"),
GREEN("Green"),
BLUE("Blue")
}
val color = Color.RED
println(color.name) // Red
Companion Objects
Companion objects are used to define static members for a class. They are declared inside a class and can access the private members of that class.
class Calc {
companion object {
fun add(a: Int, b: Int) = a + b
fun sub(a: Int, b: Int) = a - b
fun mul(a: Int, b: Int) = a * b
fun div(a: Int, b: Int) = a / b
}
}
fun main() {
println(Calc.add(1, 2))
println(Calc.sub(1, 2))
println(Calc.mul(1, 2))
println(Calc.div(1, 2))
}
Interfaces
interface Drivable {
fun drive()
}
class Car : Drivable {
override fun drive() {
println("Driving a car")
}
}
class Bike : Drivable {
override fun drive() {
println("Driving a bike")
}
}
Default implementation:
interface Printable {
fun print() {
println("Printing from Printable")
}
}
class Document : Printable {
override fun print() {
println("Printing from Document")
}
}
// Uses the default implementation of print()
class Image : Printable
Class Inheritance
open class Animal {
open fun sound() {
println("I am an animal")
}
}
class Dog : Animal() {
override fun sound() {
println("Woof!")
}
}
class Cat : Animal() {
override fun sound() {
println("Meow!")
}
}
Contructor and initialization:
open class Animal(val name: String) {
open fun makeSound() {
println("$name makes a sound")
}
}
class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("$name barks")
}
}
Visibility modifiers
-
public
is the default visibility if no modifier is specified. -
private
restricts access to within the class for class members and within the file for top-level declarations. -
protected
visibility is similar to private but allows access in subclasses. It cannot be used for top-level declarations. -
internal
restricts access to within the same module, making it useful for encapsulating implementation details that are not meant to be exposed outside the module.
Example:
class MyClass {
val myPublicProperty = "I am public"
private val myPrivateProperty = "I am private"
protected val myProtectedProperty = "I am protected"
internal val myInternalProperty = "I am internal"
}
Object extension
In Kotlin, object extensions allow you to add new functionality to existing classes without modifying their source code.
class Calc {}
fun Calc.add(a: Int, b: Int): Int = a + b
fun Calc.sub(a: Int, b: Int): Int = a - b
fun Calc.mul(a: Int, b: Int): Int = a * b
fun Calc.div(a: Int, b: Int): Int = a / b
val calc = Calc()
println(calc.add(1, 2))
println(calc.sub(1, 2))
println(calc.mul(1, 2))
println(calc.div(1, 2))
Funcional Interfaces (SAM)
An interface with only one abstract method is called a functional interface, or a Single Abstract Method (SAM) interface. The functional interface can have several non-abstract members but only one abstract member.
fun interface Calculable {
fun action(x: Double, y: Double): Double
}
fun calc(a: Double, b: Double, calc: Calculable): Double {
return calc.action(a, b)
}
fun main() {
var add = calc(2.0, 3.0) { x, y -> x + y }
var sub = calc(2.0, 3.0) { x, y -> x - y }
var mul = calc(2.0, 3.0) { x, y -> x * y }
var div = calc(2.0, 3.0) { x, y -> x / y }
}
Coroutines - basic concepts
Kotlin Coroutines is a library that allows you to write asynchronous code in a sequential way. It provides a set of suspending functions that can be called from within a coroutine.
launch
is used to start a new coroutine. It is a fire-and-forget mechanism, meaning the coroutine is started and runs concurrently with the rest of the code.
import kotlinx.coroutines.*
fun main() {
GlobalScope.launch {
// This coroutine runs in the background
delay(1000L)
println("Hello from coroutine!")
}
println("Hello from main thread!")
Thread.sleep(2000L) // Keep the main thread alive
}
runBlocking
creates a coroutine that blocks the current thread until its completion. Itβs often used in main functions and tests to bridge the gap between blocking and non-blocking code.
import kotlinx.coroutines.*
fun main() = runBlocking {
// This coroutine runs in the main thread and blocks it
launch {
delay(1000L)
println("Hello from coroutine!")
}
println("Hello from main thread!")
}
delay
is a suspending function that pauses the coroutine without blocking the underlying thread. It is used to mimic non-blocking delays.
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Start")
delay(1000L)
println("End after 1 second delay")
}
Coroutines - suspending functions
A suspending function is a function that can suspend the execution of a coroutine without blocking the thread. It is marked with the suspend
keyword.
import kotlinx.coroutines.*
suspend fun fetchData(): String {
delay(1000L) // Simulate long-running operation
return "Data fetched"
}
fun main() = runBlocking {
val data = fetchData() // Call the suspending function
println(data) // Print the result
}
Coroutines - scopes
GlobalScope
- Launches coroutines that are not bound to any specific scope.
- Use with caution as it creates global coroutines which live until the application runs.
import kotlinx.coroutines.*
fun main() {
GlobalScope.launch {
delay(1000L)
println("Hello from GlobalScope")
}
Thread.sleep(2000L) // Keep the main thread alive
}
CoroutineScope
- Defines a scope for new coroutines and manages their lifecycle.
- Use it to create structured concurrency.
import kotlinx.coroutines.*
fun main() = runBlocking {
val customScope = CoroutineScope(Dispatchers.Default)
customScope.launch {
delay(1000L)
println("Hello from CoroutineScope")
}
// Wait for the coroutine to finish
delay(2000L)
}
runBlocking
- Creates a coroutine that blocks the current thread until its completion.
- Typically used in main functions and tests.
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L)
println("Hello from runBlocking")
}
println("Hello from main thread")
}
Error Handling
try {
var result = 10 / 0
} catch (e: Exception) {
println("Error: ${e.message}")
} finally {
println("Finally")
}
Custom error handling:
class MyException(message: String) : Exception(message)
fun divide(a: Int, b: Int): Int {
if (b == 0) {
throw MyException("Division by zero")
}
return a / b
}
fun main() {
try {
val result = divide(10, 0)
println(result)
} catch (e: MyException) {
println(e.message)
} finally {
println("Finally")
}
}
Let Expression
object.let { it -> // Code to execute }
//common use
val name: String? = "Kotlin"
name?.let {
println("The length of the name is ${it.length}")
}
//temporary variable
val (a, b) = "Kotlin".let { it.length to it }
//chaining Operations
val result = "Kotlin".let { it.toUpperCase() }.let { it.reversed() }
println(result) //NILTOK
//chaining transformations
val transformed = "123"
.let { it.toInt() }
.let { it * 2 }
.let { it.toString() }
println(result) //246
Pair and Triple
Pair: is a data class that contains two values of the same type.
val pair = Pair(1, "a")
val (a, b) = pair
println(a) //1
println(b) //a
//short declaration using `to`
val pair2 = 1 to "a"
val (a, b) = pair2
println(a) //1
println(b) //a
//using pair in a function return
fun getPair(): Pair<Int, String> {
return 1 to "a"
}
val pair3 = getPair()
val (a, b) = pair3
println(a) //1
println(b) //a
Triple: is a data class that contains three values of the same type.
val triple = Triple(1, "a", true)
val (a, b, c) = triple
println(a) //1
println(b) //a
println(c) //true
Destructuring declarations
A destructuring declaration allows you to assign multiple variables at once from a single object. This is typically done using the componentN() functions that are automatically generated for data classes and can be manually defined for custom classes.
data class Person(val name: String, val age: Int, val email: String)
fun main() {
val person = Person("Alice", 30, "alice@example.com")
// Destructuring declaration
val (name, age, email) = person
println("Name: $name")
println("Age: $age")
println("Email: $email")
}
Custom destructuring declaration:
You can define your own componentN() functions to enable destructuring for custom classes.
class Point(val x: Int, val y: Int) {
operator fun component1() = x
operator fun component2() = y
}
fun main() {
val point = Point(10, 20)
// Destructuring declaration
val (x, y) = point
println("x: $x, y: $y")
}
Delegation
Delegation is a feature in Kotlin that allows you to delegate the implementation of a function or property to another object. This can be useful when you want to provide a default implementation for a function or property, or when you want to share the implementation between multiple objects.
Class delegation:
interface Base {
fun add(a: Int, b: Int): Int
fun sub(a: Int, b: Int): Int
fun mul(a: Int, b: Int): Int
fun div(a: Int, b: Int): Int
}
class BaseImpl : Base {
override fun add(a: Int, b: Int): Int { return a + b }
override fun sub(a: Int, b: Int): Int { return a - b }
override fun mul(a: Int, b: Int): Int { return a * b }
override fun div(a: Int, b: Int): Int { return a / b }
}
class Calc : Base by BaseImpl(){
override fun add(a: Int, b: Int): Int{
println("add from calc")
return a + b
}
}
class Math : Base by Calc() {
override fun sub(a: Int, b: Int): Int {
println("sub from math")
return a - b
}
}
fun main() {
val math = Math()
println(math.add(1, 2))
println(math.sub(1, 2))
println(math.mul(1, 2))
println(math.div(1, 2))
}
Property delegation:
class Person(){
//lazy delegate
val name: String by lazy {
println("Lazy initializing")
"John"
}
//observable delegate
var obs: String by Delegates.observable("Initial value"){ _, old, new ->
println("$old to $new")
}
//veto delegate called age
var age: Int by Delegates.vetoable(0) { _, old, new ->
if (new < 0) throw IllegalArgumentException("Age must be positive")
println("$old to $new")
true
}
}
fun main() {
val p = Person()
println(p.name)
println(p.obs)
p.obs = "THE NEW VALUE!!!"
println(p.obs)
//Lazy initializing
//John
//Initial value
//Initial value to THE NEW VALUE!!!
//THE NEW VALUE!!!
}
Keywords
Hard Keywords:
Keyword | Description |
---|---|
as | Used for type casting. |
as? | Safe type casting that returns null if the cast is not possible. |
break | Terminates the nearest enclosing loop. |
class | Declares a class. |
continue | Proceeds to the next iteration of the nearest enclosing loop. |
do | Used in do-while loops. |
else | Used with if for conditional branching. |
false | Boolean literal. |
for | Used for loops. |
fun | Declares a function. |
if | Conditional branching. |
in | Checks for membership in a range or collection. |
!in | Checks for non-membership in a range or collection. |
interface | Declares an interface. |
is | Checks for type compatibility. |
!is | Checks for type incompatibility. |
null | Represents a null reference. |
object | Declares an object. |
package | Specifies the package for the file. |
return | Returns from a function. |
super | Refers to the superclass implementation. |
this | Refers to the current instance. |
throw | Throws an exception. |
true | Boolean literal. |
try | Starts a try-catch block. |
typealias | Declares a type alias. |
val | Declares a read-only variable. |
var | Declares a mutable variable. |
when | Conditional branching, similar to a switch statement in other languages. |
while | Starts a while loop. |
Soft Keywords:
Keyword | Description |
---|---|
by | Used for delegation. |
catch | Used in try-catch blocks to catch exceptions. |
constructor | Declares a constructor. |
delegate | Used to specify a property delegate. |
dynamic | Marks a member as dynamic, typically used for dynamic languages interop. |
field | References the backing field of a property. |
file | Used in file annotations. |
finally | Used in try-catch blocks to execute code regardless of whether an exception is thrown. |
get | Defines a getter for a property. |
import | Imports a package, class, or function. |
init | Declares an initializer block. |
param | Used in annotations to reference constructor parameters. |
property | Used in annotations to reference properties. |
receiver | Used in annotations to reference the receiver parameter. |
set | Defines a setter for a property. |
setparam | Used in annotations to reference setter parameters. |
where | Specifies type constraints in generic declarations. |
Modifier Keywords:
Keyword | Description |
---|---|
abstract | Marks a class or member as abstract, meaning it cannot be instantiated or must be overridden. |
annotation | Declares an annotation class. |
companion | Declares a companion object inside a class. |
const | Marks a property as a compile-time constant. |
crossinline | Ensures that a lambda parameter is not inlined at the call site. |
data | Declares a data class, which automatically generates useful methods like equals and hashCode . |
enum | Declares an enumeration class. |
expect | Declares expected declarations in multiplatform projects. |
external | Marks a function or property as implemented outside of Kotlin (e.g., in C/C++). |
final | Prohibits a class or member from being overridden. |
infix | Allows a function to be called using infix notation. |
inline | Requests the compiler to inline the function to improve performance. |
inner | Allows an inner class to access members of its outer class. |
internal | Restricts visibility to the same module. |
lateinit | Defers property initialization. |
noinline | Ensures that a lambda parameter is not inlined. |
open | Allows a class or member to be overridden. |
operator | Marks a function as an operator overload. |
out | Indicates that a type parameter is covariant. |
override | Indicates that a member is overriding a member in a superclass. |
private | Restricts visibility to the same class. |
protected | Restricts visibility to the same class and subclasses. |
public | Specifies that the member is visible everywhere (default visibility). |
reified | Allows a type parameter to be accessed at runtime. |
sealed | Declares a sealed class, which restricts subclassing to the same file. |
suspend | Marks a function as suspending (usable in coroutines). |
tailrec | Marks a function as tail-recursive to optimize recursion. |
vararg | Allows a function to accept a variable number of arguments. |
Specified identifiers:
Identifier | Description |
---|---|
field | Refers to the backing field of a property. Used inside custom getter and setter functions. |
it | The default name for the single parameter in a lambda expression if no explicit name is provided. |