Эквивалент конструкции Swift 'if let' в Kotlin для безопасной работы с nullable-типами
Прямой аналог Swift `if let` в Kotlin
В Kotlin нет точного синтаксического аналога `if let`, но есть несколько способов достичь того же результата. Самый близкий — использовать let вместе с оператором безопасного вызова ?..
1. Использование `?.let` (рекомендуемый способ)
Это наиболее идиоматичный способ в Kotlin, который максимально напоминает Swift `if let`:
var name: String? = "Alice"
name?.let { unwrappedName ->
println("Hello, $unwrappedName")
} ?: run {
println("Name is null")
}
Как это работает:
name?.let { ... }— еслиnameне null, то внутриletпеременнаяunwrappedNameбудет иметь типString(не nullable), а неString?.?: run { ... }— это аналогelseв Swift. Еслиnameравно null, выполняется блокrun.
Если вам не нужен блок else, можно просто:
name?.let { println("Hello, $it") }
Здесь it — это неявное имя переменной внутри лямбды.
2. Smart cast (умное приведение) — для val
Если переменная объявлена как val (неизменяемая), Kotlin автоматически выполняет smart cast после проверки на null:
val name: String? = "Alice"
if (name != null) {
println("Hello, $name") // name автоматически приведён к String
} else {
println("Name is null")
}
Это работает только для val и для var, которые не изменяются между проверкой и использованием (компилятор отслеживает это).
3. Использование `when` для нескольких nullable-переменных
Если нужно извлечь несколько nullable-значений (как в Swift можно сделать if let a = a, let b = b):
val firstName: String? = "John"
val lastName: String? = "Doe"
when {
firstName != null && lastName != null -> {
println("Full name: $firstName $lastName")
}
else -> {
println("One of the names is null")
}
}
Или более элегантно с ?.let и вложенными вызовами:
firstName?.let { fName ->
lastName?.let { lName ->
println("Full name: $fName $lName")
}
}
4. Функция `requireNotNull` для быстрого извлечения с исключением
Если вы уверены, что значение не null, но хотите явно извлечь его (аналог Swift guard let с early return):
fun greet(name: String?) {
val unwrappedName = requireNotNull(name) { "Name must not be null" }
println("Hello, $unwrappedName")
}
Это выбросит IllegalArgumentException с указанным сообщением, если значение null.
Сравнение со Swift
- Swift:
if let unwrapped = optional { ... } - Kotlin:
optional?.let { unwrapped -> ... }
Оба подхода создают новую неизменяемую переменную с non-null типом внутри блока. Разница в синтаксисе: Swift использует ключевые слова, Kotlin — функции высшего порядка.
Рекомендую привыкнуть к ?.let — это самый распространённый и читаемый способ в сообществе Kotlin.
Альтернативный подход: Elvis-оператор и ранний возврат
Если вы привыкли к стилю Swift с guard let, который позволяет выйти из функции при nil, в Kotlin можно использовать комбинацию Elvis-оператора ?: и раннего возврата:
fun processName(name: String?) {
val unwrappedName = name ?: return // если null — выходим
println("Hello, $unwrappedName")
// здесь unwrappedName имеет тип String (не nullable)
}
Этот подход особенно полезен, когда вам нужно извлечь значение в начале функции и использовать его дальше, не углубляя вложенность. В Swift это выглядело бы так:
func processName(name: String?) {
guard let unwrappedName = name else { return }
print("Hello, \(unwrappedName)")
}
В Kotlin также можно использовать ?: для присваивания значения по умолчанию:
val name: String? = null
val safeName = name ?: "Default Name"
println(safeName) // "Default Name"
Для более сложной логики с несколькими nullable-значениями можно комбинировать:
fun process(first: String?, last: String?) {
val firstName = first ?: return
val lastName = last ?: return
println("$firstName $lastName")
}
Этот стиль делает код плоским и легко читаемым, избегая "пирамиды" из вложенных ?.let.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги