kotlinadvanced
Context Receivers — Scoped Functions
Use context receivers for scoped function access: transaction contexts, logging contexts, and DSL building.
kotlinPress ⌘/Ctrl + Shift + C to copy
// Context receivers (Kotlin 1.6.20+ experimental)
// Compile with: -Xcontext-receivers
// Logger context
interface Logger {
fun log(message: String)
}
class ConsoleLogger : Logger {
override fun log(message: String) = println("[LOG] $message")
}
// Transaction context
class Transaction(val id: String) {
private val operations = mutableListOf<String>()
var committed = false; private set
fun addOperation(op: String) {
check(!committed) { "Transaction already committed" }
operations.add(op)
}
fun commit() {
committed = true
println("Transaction $id committed: ${operations.size} operations")
}
fun rollback() {
operations.clear()
println("Transaction $id rolled back")
}
}
// Functions with context receivers
context(Logger)
fun processOrder(orderId: String) {
log("Processing order: $orderId")
// can use log() directly since Logger is in context
}
context(Logger, Transaction)
fun createOrder(userId: String, items: List<String>) {
log("Creating order for user: $userId")
addOperation("INSERT INTO orders ...")
items.forEach { item ->
log("Adding item: $item")
addOperation("INSERT INTO order_items ($item)")
}
}
context(Transaction)
fun saveAuditLog(action: String) {
addOperation("INSERT INTO audit_log ('$action')")
}
// Context receiver on class
context(Logger)
class OrderService {
fun placeOrder(userId: String, items: List<String>) {
log("OrderService.placeOrder")
// has Logger in scope
}
}
// Context receiver with extension functions
context(Logger)
fun String.logAndUppercase(): String {
log("Transforming: $this")
return uppercase()
}
// Builder pattern with context
interface HtmlScope {
fun tag(name: String, content: String)
fun text(content: String)
}
class HtmlBuilder : HtmlScope {
private val parts = mutableListOf<String>()
override fun tag(name: String, content: String) {
parts.add("<$name>$content</$name>")
}
override fun text(content: String) { parts.add(content) }
fun build() = parts.joinToString("\n")
}
context(HtmlScope)
fun header(title: String) {
tag("h1", title)
}
context(HtmlScope)
fun paragraph(text: String) {
tag("p", text)
}
fun buildHtml(block: context(HtmlScope) () -> Unit): String {
val builder = HtmlBuilder()
block(builder)
return builder.build()
}
// Simulated usage (requires -Xcontext-receivers)
fun main() {
val logger = ConsoleLogger()
// Provide context
with(logger) {
processOrder("ORD-001")
val tx = Transaction("TX-001")
with(tx) {
createOrder("user-1", listOf("laptop", "mouse"))
saveAuditLog("order_created")
tx.commit()
}
}
// HTML builder with context
println("\n--- HTML ---")
val html = buildHtml {
header("Welcome")
paragraph("This is a context receiver demo.")
paragraph("Clean and type-safe!")
}
println(html)
}Use Cases
- Transaction and logging scope management
- Type-safe builder patterns
- Cross-cutting concern injection
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinadvanced
Contracts — Smart Cast Effects
Use Kotlin contracts to help the compiler with smart casting: returns, callsInPlace, and custom implications.
Best for: Custom null-safety assertions
#kotlin#contracts
kotlinbeginner
Null Safety — Elvis, Safe Call, and let
Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.
Best for: Safe navigation through nullable chains
#kotlin#null-safety
kotlinbeginner
Data Classes — Copy, Destructure, and Equals
Use data classes for immutable models: auto-generated equals, hashCode, copy, and destructuring.
Best for: Immutable domain models and DTOs
#kotlin#data-class
kotlinbeginner
Extension Functions and Properties
Add methods to existing classes without inheritance: extension functions, properties, and generic extensions.
Best for: Adding utility methods to third-party types
#kotlin#extensions