Quick Reference
| Topic | File |
|---|---|
| Null safety operators and patterns | nullsafety.md |
| Coroutines, flows, structured concurrency | coroutines.md |
| Collections, sequences, data classes | collections.md |
| Scope functions, extensions, sealed classes | idioms.md |
| Java interop and common Kotlin mistakes | interop.md |
| Android lifecycle, Compose state | android.md |
| Delegation, inline, reified, multiplatform | advanced.md |
Critical Rules
Null Safety
!!asserts non-null — crashes on null, use only when you've already checked- Platform types from Java are risky — add null checks or use
@Nullable/@NonNullannotations - Elvis with
return/throwfor early exit —val name = user?.name ?: return
Coroutines
viewModelScopeauto-cancels on ViewModel clear — don't useGlobalScopein Android- Structured concurrency: child coroutine failure cancels parent — use
supervisorScopeto isolate StateFlowneeds initial value and never completes —SharedFlowfor one-shot events- Inject dispatchers for testability — don't hardcode
Dispatchers.IO
Collections & Data Classes
first()throws on empty — usefirstOrNull()for safe access- Only constructor properties in
equals/hashCode— body properties ignored mutableStateListOffor Compose — wrappingmutableListOfin state won't track changes
Scope Functions & Extensions
- Don't nest scope functions — readability drops fast, extract to named functions
- Extensions are resolved statically — not polymorphic, receiver type matters at compile time
Android/Compose
repeatOnLifecycle(STARTED)for flow collection —launchWhenStartedis deprecatedremembersurvives recomposition only — userememberSaveablefor config changescollectAsStateWithLifecycleis the gold standard — lifecycle-aware + Compose state
Java Interop
==is structural equality in Kotlin —===for reference, opposite of Java- SAM conversion only for Java interfaces — Kotlin interfaces need explicit
fun interface @JvmStatic,@JvmOverloads,@JvmFieldfor Java-friendly APIs