Skip to content

Instantly share code, notes, and snippets.

@vitalikas
Created December 11, 2025 07:12
Show Gist options
  • Select an option

  • Save vitalikas/ec07d5a9bf0c1604f15eb9809db65fbb to your computer and use it in GitHub Desktop.

Select an option

Save vitalikas/ec07d5a9bf0c1604f15eb9809db65fbb to your computer and use it in GitHub Desktop.
Inline, noinline and crossinline example in Kotlin
/**
* 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