The document discusses the Kotlin programming language. It highlights that Kotlin is a modern, pragmatic language that provides good tooling and interoperability with Java. It has grown significantly in popularity since its initial release. The document then discusses various features of Kotlin like its concise and readable syntax, null safety, support for lambdas and extensions, and how it can be used for multi-platform projects. Kotlin aims to be an improvement over Java by making code more concise, safe, and expressive while maintaining interoperability with existing Java code and libraries.
15. public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
33. Nullable Types Under the Hood
No performance overhead
@Nullable, @NotNull annotations
34. class Optional<T>(val value: T) {
fun isPresent() = value != null
fun get() = value ?:
throw NoSuchElementException("No value present")
}
Nullable types ≠ Optional
35. Using annotated Java types from Kotlin
Type
behaves like
regular Java type
@ParametersAreNonnullByDefault
@Nullable
@NotNull Type
Type?
Type
Type
@MyNonnullApi
Type/
Type?
41. fun String.lastChar() = get(length - 1)
this can be omitted
Extension Functions
fun String.lastChar() = this.get(this.length - 1)
42. fun String.lastChar() = get(length - 1)
Calling Extension Functions
from Java code
StringExtensions.kt
char c = StringExtensionsKt.lastChar("abc");
JavaClass.java
import static StringExtensionsKt.lastChar;
char c = lastChar("abc");
43. No. Because it’s a regular
static method under the hood.
fun String.lastChar() = get(length - 1)
Extension Functions
Is it possible to call a private
member of String here?
46. { employee: Employee -> employee.city == City.PRAGUE }
What’s an average
age of employees
working in Prague?
Working with collections with Lambdas
val employees: List<Employee>
employees.filter { it.city == City.PRAGUE }.map { it.age }.average()
data class Employee(
val city: City, val age: Int
)
47. What’s an average
age of employees
working in Prague?
Working with collections with Lambdas
val employees: List<Employee>
data class Employee(
val city: City, val age: Int
)
extension functions
employees.filter { it.city == City.PRAGUE }.map { it.age }.average()
50. val sb = StringBuilder()
with (sb) {
appendln("Alphabet: ")
for (c in 'a'..'z') {
append(c)
}
toString()
}
The with function
with is a function
val sb = StringBuilder()
sb.appendln("Alphabet: ")
for (c in 'a'..'z') {
sb.append(c)
}
sb.toString()
51. val sb = StringBuilder()
with (sb) {
this.appendln("Alphabet: ")
for (c in 'a'..'z') {
this.append(c)
}
this.toString()
}
val sb = StringBuilder()
with (sb, { ->
this.appendln("Alphabet: ")
for (c in 'a'..'z') {
this.append(c)
}
this.toString()
})
lambda
is its
second
argument
Lambda with receiverwith is a function
this is
an implicit receiver
in the lambda
val sb = StringBuilder()
with (sb) {
appendln("Alphabet: ")
for (c in 'a'..'z') {
append(c)
}
toString()
}
this can be omitted
52. Lambda with receiver
val sb = StringBuilder()
with (sb) {
appendln("Alphabet: ")
for (c in 'a'..'z') {
this.append(c)
}
}
lambda with
implicit this
54. with (window) {
width = 300
height = 200
isVisible = true
}
The with function
class Window(
var width: Int,
var height: Int,
var isVisible: Boolean
)
55. window.width = 300
window.height = 200
window.isVisible = true
with (window) {
width = 300
height = 200
isVisible = true
}
Inline functions
is declared as
inline function
generated bytecode is similar to:
No performance overhead for creating a lambda!
56. The apply function
val mainWindow =
windowById["main"]?.apply {
width = 300
height = 200
isVisible = true
} ?: return
Applies the given actions
and returns receiver as a result:
63. Sharing common code
• Sharing business logic
• Keeping UI platform-dependent
• The shared part might vary
64. Common code
• you define expect declarations in the common
code and use them
• you provide different actual implementations
for different platforms
65. Time measurement example
expect fun measureTime(action: () -> Unit): Duration
Expected platform-specific API:
Expected API can be used in the common code:
measureTime {
// operation
}
66. Platform-specific Implementations
expect fun measureTime(action: () -> Unit): Duration
actual fun measureTime(action: () -> Unit): Duration {
// implementation using System.nanoTime()
}
actual fun measureTime(action: () -> Unit): Duration {
// implementation using window.performance.now()
}
actual fun measureTime(action: () -> Unit): Duration {
// implementation using std::chrono::high_resolution_clock
}
Kotlin/JVM
Kotlin/JS
Kotlin/Native
67. Common code
• can use the standard library
• can define expect declarations and use them
• can use other multi-platform libraries
69. Many apps already in production
Going Native: How I used Kotlin Native to Port 6 years
of Android Game Code to iOS in 6 months
Shipping a Mobile Multiplatform Project on iOS &
Android
Your Multiplatform Kaptain has Arrived: iOS release is
powered by Kotlin Multiplatform