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