Created
December 11, 2025 07:12
-
-
Save vitalikas/ec07d5a9bf0c1604f15eb9809db65fbb to your computer and use it in GitHub Desktop.
Inline, noinline and crossinline example in Kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Demonstrates inline, noinline, and crossinline in one function. | |
| * | |
| * - onSuccess: regular inline lambda - you can use 'return' to exit the calling function | |
| * - noinline onError: can be passed to other functions that expect function types | |
| * - crossinline onComplete: inline but called later (e.g., in a callback), no 'return' allowed | |
| */ | |
| inline fun String.validateEmail( | |
| onSuccess: () -> Unit, | |
| noinline onError: (String) -> Unit, | |
| crossinline onComplete: () -> Unit | |
| ) { | |
| println("→ Starting validation for: $this") | |
| // Regular inline lambda - called directly | |
| if (this.contains("@")) { | |
| println(" Valid format detected") | |
| onSuccess() // Can use 'return' inside this lambda | |
| } else { | |
| println(" Invalid format detected") | |
| // noinline lambda - can be passed to another function | |
| // This only works because onError is noinline! | |
| logErrorToAnalytics( | |
| email = this, | |
| message = "Missing @ symbol", | |
| errorCallback = onError | |
| ) | |
| } | |
| // crossinline lambda - called at the end if no non-local return happened | |
| // Called from a different context (inside an object) | |
| // If onSuccess contains 'return', this won't be reached because the return exits validateEmail() | |
| println(" Executing completion callback...") | |
| val callback = object { | |
| fun execute() { | |
| onComplete() // Must be crossinline to use here (no 'return' allowed) | |
| } | |
| } | |
| callback.execute() | |
| println("→ Validation finished for: $this\n") | |
| } | |
| // This function accepts a function type parameter | |
| // We can pass the noinline lambda here | |
| fun logErrorToAnalytics( | |
| email: String, | |
| message: String, | |
| errorCallback: (String) -> Unit | |
| ) { | |
| println("✗ Invalid email: $email. Logging to analytics: $message") | |
| errorCallback(message) // Invoke the callback | |
| } | |
| fun validateUsersList(emails: List<String>): List<String> { | |
| val validEmails = mutableListOf<String>() | |
| println("Validating ${emails.size} emails...\n") | |
| // forEach is inline, so we can use non-local return | |
| emails.forEach { email -> | |
| println("━━━ Checking: $email ━━━") | |
| var isValid = false | |
| email.validateEmail( | |
| onSuccess = { | |
| println(" [onSuccess] Valid! Checking if already registered...") | |
| isValid = true | |
| // Regular inline lambda - CAN use 'return' to exit forEach iteration | |
| // Example: early exit if email is already registered | |
| if (email in validEmails) { | |
| println(" [onSuccess] Already registered, skipping... \n") | |
| return@forEach // Exit immediately - skips adding and onComplete! | |
| } | |
| println(" [onSuccess] New email, will add to list") | |
| }, | |
| onError = { error -> | |
| // noinline lambda - CANNOT use 'return' here | |
| // This is passed to logErrorToAnalytics(), so it must be a real function object | |
| println(" [onError] $error") | |
| }, | |
| onComplete = { | |
| // crossinline lambda - runs at end if no non-local return happened | |
| // It's called from inside an object callback, so it needs crossinline | |
| // CANNOT use 'return' here because it would be unclear what to exit | |
| println(" [onComplete] Validation process finished") | |
| } | |
| ) | |
| if (isValid) { | |
| validEmails.add(email) | |
| println(" ✓ Added to valid list\n") | |
| } else { | |
| println(" ✗ Not added\n") | |
| } | |
| } | |
| println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") | |
| println("Result: ${validEmails.size} valid emails") | |
| return validEmails | |
| } | |
| fun main() { | |
| val testEmails = listOf( | |
| "[email protected]", | |
| "[email protected]", // Duplicate - will trigger early return | |
| "[email protected]", | |
| "user455", | |
| "[email protected]" | |
| ) | |
| val validEmails = validateUsersList(testEmails) | |
| println("\nFinal result: $validEmails") | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment