Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Kotlin Advanced Concepts: Lambda With Receiver, Wildcards, Where Clause, and Delegates

Tech 1

1. Lambda with Receiver

package com.example.lambdawithreceiver

fun <T> T.executeBlock(block: T.() -> Unit) {
    this.block()
}

fun <T> runWithParameter(receiver: T, block: T.() -> Unit) {
    receiver.block()
}

fun main() {
    5.executeBlock {
        println(this * 3)
    }

    runWithParameter("Hello") {
        println(this.length)
    }
}

2. Star Projection (Wildcard)

package com.example.wildcard

fun main() {
    val mixedList: List<*> = listOf(42, "Kotlin", null, 3.14)
    mixedList.forEach { element ->
        println(element is Double)
    }
}

3. Where Clause for Generic Constraints

package com.example.genericconstraints

interface Printable
interface Serializable
interface Comparable<T>

class Product : Printable, Serializable, Comparable<Product> {
    override fun compareTo(other: Product): Int = 0
}

class DataHolder<T>(val item: T) where T : Printable, T : Serializable, T : Comparable<T> {
    fun logItem() {
        println("Holding: $item")
    }
}

fun <T> validate(item: T) where T : Printable, T : Serializable, T : Comparable<T> {
    println("Validation passed for $item")
}

fun main() {
    val holder = DataHolder(Product())
    holder.logItem()
    validate(Product())
}

4. Out and In Keywords (Covariance/Contravariance)

out marks a type parameter as covariant (read-only, producer), allowing subclass instances to be assigned to supertype variables. in marks a type parameter as contravarient (write-only, consumer), allowing supertype instances to be assigned to subclas variables.

5. Delegation

5.1 Interface Delegation

package com.example.interfacedelegation

interface UserRepository {
    fun fetchAllUsers(): List<String>
}

interface OrderRepository {
    fun fetchOrderById(id: Int): String
}

class UserRepositoryImpl : UserRepository {
    override fun fetchAllUsers(): List<String> = listOf("Alice", "Bob")
}

class OrderRepositoryImpl : OrderRepository {
    override fun fetchOrderById(id: Int): String = "Order #$id"
}

class DataService(
    userRepo: UserRepositoryImpl,
    orderRepo: OrderRepositoryImpl
) : UserRepository by userRepo,
    OrderRepository by orderRepo {
    fun fetchCachedData(): String = "Cached data"
}

fun main() {
    val dataService = DataService(UserRepositoryImpl(), OrderRepositoryImpl())
    println(dataService.fetchAllUsers())
    println(dataService.fetchOrderById(101))
    println(dataService.fetchCachedData())
}

5.2 Property Delegation

package com.example.propertydelegation

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class ConfigManager : ReadWriteProperty<Settings, String> {
    private var internalValue = "default"
    override fun getValue(thisRef: Settings, property: KProperty<*>): String {
        println("Reading property: ${property.name}")
        return internalValue
    }
    override fun setValue(thisRef: Settings, property: KProperty<*>, value: String) {
        println("Writing property: ${property.name}, New value: $value")
        internalValue = value
    }
}

class Settings {
    var appVersion: String by ConfigManager()
    var apiKey: String by ConfigManager()
}

fun main() {
    val appSettings = Settings()
    appSettings.appVersion = "2.1.0"
    println(appSettings.appVersion)
}

5.3 Lazy Delegation

package com.example.lazydelegation

class ReportGenerator {
    val compiledData: String by lazy {
        println("Compiling report data...")
        "Monthly Report: October 2024"
    }
}

fun main() {
    val generator = ReportGenerator()
    println("Report generator initialized")
    println(generator.compiledData)
    println(generator.compiledData) // No recompilation
}

5.4 Observable Property Delegatino

package com.example.observabledelegation

import kotlin.properties.Delegates

fun main() {
    var temperature by Delegates.observable(25) {
        property, oldValue, newValue ->
        println("${property.name} changed from $oldValue°C to $newValue°C")
    }
    temperature = 30
    temperature = 22
    println(temperature)
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.