← Back to Kotlin Course | Chapter 5: Null Safety | Lesson 5 of 6

let, run, also, apply, with क्या हैं

ये पांच words किसी value के साथ कुछ करने और बाद में आपको क्या मिलता है यह तय करने के लिए Kotlin के छोटे helpers का toolbox हैं।
Syntax
kotlin
val r1 = receiver.let { /* it -> */ result }
val r2 = receiver.run { /* this -> */ result }
val r3 = receiver.also { /* it -> */ }     // returns receiver
val r4 = receiver.apply { /* this -> */ }   // returns receiver
val r5 = with(receiver) { /* this -> */ result }

let for Null Checks and Transformations

let receiver को it के रूप में उपलब्ध कराते हुए एक block execute करता है और block जो भी produce करे वह return करता है, और इसे आमतौर पर ?. के साथ combine किया जाता है ताकि code सिर्फ तभी चले जब एक nullable value मौजूद हो।

उदाहरण: let for Null Checks and Transformations

markup
// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `name` (a `String?`), set to `"Kotlin"`
    val name: String? = "Kotlin"
    // Call `name?.let` with a trailing lambda, storing the result in `length`
    val length = name?.let {
        // Print "Name is not null: $it" to the console, with a trailing newline
        println("Name is not null: $it")
        it.length
    }
    // Print "Length: $length" to the console, with a trailing newline
    println("Length: $length")
}

run for Grouped Computation

run receiver को this के रूप में उपलब्ध कराते हुए एक block execute करता है, block का result return करते हुए -- उस receiver के members को सीधे शामिल करने वाले कई steps से एक value compute करने के लिए उपयोगी।

उदाहरण: run for Grouped Computation

markup
// Define a class `Config`
class Config(var name: String = "", var port: Int = 8080)

// Entry point: execution of the program starts here
fun main() {
    // Call `Config().run` with a trailing lambda, storing the result in `summary`
    val summary = Config().run {
        name = "Server"
        port = 9090
        "$name running on port $port"
    }
    // Print `summary` to the console, with a trailing newline
    println(summary)
}

also for Side Effects

also receiver को it के रूप में एक block चलाता है लेकिन हमेशा original receiver को बिना बदले return करता है, जो इसे calls की chain के बीच में logging या debugging के लिए आदर्श बनाता है।

उदाहरण: also for Side Effects

markup
// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `numbers`, set to `mutableListOf(1, 2, 3)`
    val numbers = mutableListOf(1, 2, 3)
        .also { println("Original list: $it") }
    // Add `4` to `numbers`
    numbers.add(4)
    // Print "After adding: $numbers" to the console, with a trailing newline
    println("After adding: $numbers")
}

apply for Configuring an Object

apply receiver को this के रूप में एक block चलाता है और वही receiver return करता है, इसे एक expression में किसी newly created object पर कई properties सेट करने के लिए perfect बनाते हुए।

उदाहरण: apply for Configuring an Object

markup
// Define a class `Person`
class Person {
    // Declare a mutable variable `name` (a String), initialized to `""`
    var name: String = ""
    // Declare a mutable variable `age` (an Int), initialized to `0`
    var age: Int = 0
}

// Entry point: execution of the program starts here
fun main() {
    // Call `Person().apply` with a trailing lambda, storing the result in `person`
    val person = Person().apply {
        name = "Ana"
        age = 30
    }
    // Print "${person.name}, ${person.age}" to the console, with a trailing newline
    println("${person.name}, ${person.age}")
}

with for Operating on an Existing Object

with(receiver) { ... } कोई extension function नहीं बल्कि एक regular function है जो एक object और एक lambda लेता है जहां वह object this के रूप में उपलब्ध होता है, lambda का result return करते हुए -- तब उपयोगी जब आपके पास पहले से object हाथ में हो।

उदाहरण: with for Operating on an Existing Object

markup
// Define a class `Rectangle`
class Rectangle(val width: Int, val height: Int)

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `rect`, set to `Rectangle(4, 5)`
    val rect = Rectangle(4, 5)
    // Call `with(rect)` with a trailing lambda, storing the result in `area`
    val area = with(rect) {
        width * height
    }
    // Print "Area: $area" to the console, with a trailing newline
    println("Area: $area")
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. apply और also को मिला देना; apply खुद receiver (this) return करता है जबकि also भी receiver return करता है लेकिन इसे it के रूप में उजागर करता है।
  2. let और run को मिला देना; दोनों this/it का अलग-अलग उपयोग करते हैं और lambda का result return करते हैं, यह भूलना आसान है कि कौन सा किसका उपयोग करता है।
  3. कई असंबंधित operations को साथ chain करने के लिए scope functions का ज़्यादा उपयोग करना, code को साधारण statements से ज़्यादा मुश्किल बनाते हुए।
चैप्टर सारांश
  • let value को it के रूप में एक block चलाता है और block का result return करता है -- अक्सर null checks के लिए ?. के साथ उपयोग होता है।
  • run value को this के रूप में एक block चलाता है और block का result return करता है।
  • also value को it के रूप में एक block चलाता है लेकिन original value return करता है -- logging जैसे side effects के लिए अच्छा।
  • apply value को this के रूप में एक block चलाता है और original value return करता है -- किसी object को configure करने के लिए अच्छा।
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.