What does the expression `name?.let { it.uppercase() } ?: "UNKNOWN"` do, and how does it handle a null `name`?
answer
- ?. runs let only when non-null
- ?: supplies the fallback
- it is smart-cast to non-null inside let
- whole thing is one expression
- elvis fires if let also returns null
basics
~10 sIf name is not null, it runs the block and uppercases it. If name is null, the block is skipped and the whole expression becomes "UNKNOWN". The Elvis operator (?:) supplies the fallback.
solid answer
~40 s`?.` is the safe-call operator: `name?.let { ... }` invokes `let` only when `name` is non-null, otherwise the whole `?.let{...}` short-circuits to `null`. Inside `let`, the receiver is passed as the lambda argument `it`, already smart-cast to the non-nullable type, so `it.uppercase()` is safe. The Elvis operator `?:` then says: if the left side is `null`, evaluate the right side instead. So a non-null `name` yields its uppercased value; a null `name` makes `?.let` produce `null`, and `?:` substitutes `"UNKNOWN"`. This is the canonical `?.let {} ?: default` pattern for transform-or-default on a nullable. It avoids an explicit `if (name != null)` check and keeps the value as a single expression.
code
kotlin · 5 linesfun greet(name: String?): String =
name?.let { "Hello, ${it.uppercase()}" } ?: "Hello, stranger"
println(greet("ada")) // Hello, ADA
println(greet(null)) // Hello, strangergo deeper
Reads the pattern correctly: block runs only when non-null, Elvis gives the default; knows it is the non-null value.
Notes it is one expression usable as an initializer, and that the fallback also fires when the lambda returns null.
Distinguishes 'name is null' from 'lambda returned null' and chooses the form deliberately; mentions smart-cast inside the block.
Frames this as a readability/intent tradeoff vs. if/early-return, and flags the lambda-returns-null edge as a correctness hazard in code review.
## The operators involved - **`?.` (safe call):** `a?.b` evaluates to `a.b` when `a` is non-null, otherwise to `null` without throwing a `NullPointerException`. The whole chain short-circuits the moment a receiver is null. - **`let`:** a scope function. `x.let { block }` passes `x` into the lambda as the implicit parameter `it` and returns whatever the lambda returns. - **`?:` (Elvis):** `a ?: b` evaluates to `a` if `a` is non-null, otherwise to `b`. ## Putting them together ```kotlin val result: String = name?.let { it.uppercase() } ?: "UNKNOWN" ``` Step by step when `name: String?`: 1. If `name` is **non-null**, `?.` calls `let`. Inside the block `it` is `name` smart-cast to non-nullable `String`, so `it.uppercase()` compiles and runs. `let` returns that uppercased string, and `?:` leaves it untouched. 2. If `name` is **null**, `?.let { ... }` short-circuits to `null` (the lambda never runs). `?:` then yields the fallback `"UNKNOWN"`. ## Why use this instead of an if-check It is a single **expression**, so it can initialize a `val`, be returned directly, or be passed as an argument. The transformation (`uppercase()`) and the default both live in one place. ## A subtle trap If the lambda itself can return `null`, the Elvis branch also fires for that case: ```kotlin val r = map[key]?.let { transform(it) } ?: fallback // fallback also used if transform returns null ``` That is sometimes desired, sometimes a bug — be deliberate about it.
- If `name` is `"ada"` but `it.uppercase()` somehow returned null, what would the expression yield?It would yield the Elvis fallback `"UNKNOWN"`, because `?:` fires whenever the left side is null — including when the lambda returns null, not only when `name` is null.
- What is `it` here and what type does it have?`it` is the implicit single parameter of `let` — it is `name` smart-cast to the non-nullable type `String` inside the block.
Like a vending machine: insert a valid coin (non-null) and you get the snack transformed by the machine; insert nothing and the machine just hands back the default 'sold out' card.
saying these in an interview costs you the question
- Saying the block still runs when name is null
- Claiming ?. throws when the receiver is null
- Confusing ?: (Elvis) with ?. (safe call)
- Thinking it is nullable inside the let block
- Not realizing the fallback also triggers if the lambda returns null