Optionality
Optionality
Intro
Optional values which can be null or have a value. Determined at runtime or compile time
Code
fun myFunction(name: String? = null) {
val displayName = name ?: "defaultName"
println("Name: $displayName")
}
fun main() {
myFunction() // Output: Name: defaultName
myFunction("Bob") // Output: Name: Bob
myFunction(null) // Output: Name: defaultName
}
Check optionality
Do if true || not null
fun processNullableString(text: String?) {
// Safe call operator: executes the lambda only if 'text' is not null
text?.let {
println("The text is: $it")
}
if else
if else statement?
fun processNullableString(text: String?) {
if (text != null) {
// 'text' is not null, safe to use it directly
println("The text is: $text")
// Perform operations on 'text'
} else {
// 'text' is null
println("The text is null")
// Handle the case where 'text' is null
}
}
if let
If let equivalent in kotlin ?. let { } ?: run { }
swift counterpart
fun process(text: String?) {
text?.let {
// Code to execute if text is not null
println("Text is not null: $it")
} ?: run {
// Code to execute if text is null (else block)
println("Text is null")
}
}
Default value
var name: String? = null
val defaultName = name ?: "Sensehack"
println(defaultName)
name = "Kay"
val assignedName = name ?: "Kautilya"
println(assignedName)
Mind Map
Swift counterpart Optionals
If let optional
One option is to use a safe cast operator + safe call + let:
(getUser() as? User)?.let { user ->
...
}
Another would be to use a smart cast inside the lambda passed to let:
getUser().let { user ->
if (user is User) {
...
}
}
But maybe the most readable would be to just introduce a variable and use a smart cast right there:
val user = getUser()
if (user is User) {
...
}
also
In Kotlin, also is a scope function that operates on an object and returns the object itself after executing a block of code. It's useful for performing side effects or additional operations on an object without modifying it or interrupting method chaining. The object is referenced within the also block using it (by default) or a custom name if specified.
fun main() {
val numbers = mutableListOf(1, 2, 3)
val result = numbers.also {
println("Original list: $it") // Prints: Original list: [1, 2, 3]
it.add(4)
}
println("Modified list: $result") // Prints: Modified list: [1, 2, 3, 4]
}
swift guard
guard let e = email.text , !e.isEmpty else { return }
val e = email.text?.let { it } ?: return
if let
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
let
In Kotlin, the let function's return type defaults to Unit if the lambda expression within it does not explicitly return a value. Unit is Kotlin's equivalent of void in Java, signifying that a function does not return a meaningful value.
When a let block's last expression is a statement that doesn't produce a value (like a variable assignment or a for loop without a return), the let function implicitly returns Unit. However, if the lambda contains an expression that yields a value, that value becomes the return value of the let function.
suspend fun openInBrowser(url: String): Pair<Boolean, LoginData?> {
val loginData = callbackData?.let {
println("Successful callback!")
it
} ?: run {
println("Failure in authenticating with user credentials")
return Pair(false, null)
}
}