@@ -396,5 +396,55 @@ public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
396
396
* assertTrue(str.startsWith("kot")) vs str should startWith("kot")
397
397
* lambdas with
398
398
receivers: the key feature that helps establish the grammar of DSL s
399
- *
399
+ * In effect, you
400
+ can give one of the parameters of the lambda the special status of a receiver, letting you
401
+ refer to its members directly without any qualifier
402
+ * builderAction: StringBuilder.() -> Unit // Declares a parameter of a function type with a receiver
403
+ * StringBuilder().builderAction() // Passes a StringBuilder as a receiver to the lambda
404
+ val stringAction: String.() -> Unit = { println(this + "buba") }
405
+
406
+ stringAction("asd")
407
+ "viap".stringAction()
408
+ * String.(Int, Int) -> Unit
409
+ * receiver type: String
410
+ * parameter types: (Int, Int)
411
+ * Return type: Unit
412
+ * Why an extension function type? The idea of accessing members of an external type
413
+ without an explicit qualifier may remind you of extension functions, which allow you
414
+ to define your own methods for classes defined elsewhere in the code. Both extension
415
+ functions and lambdas with receivers have a receiver object, which has to be provided
416
+ when the function is called and is available in its body. In effect, an extension function
417
+ type describes a block of code that can be called as an extension function.
418
+ * The way you invoke the variable also changes when you convert it from a regular
419
+ function type to an extension function type. Instead of passing the object as an argu-
420
+ ment, you invoke the lambda variable as if it were an extension function.
421
+ * builderAction
422
+ here isn’t a method declared on the StringBuilder class; it’s a parameter of a func-
423
+ tion type that you call using the same syntax you use to call extension functions
424
+ * Note that a lambda with a receiver looks exactly the same as a regular lambda in the
425
+ source code. To see whether a lambda has a receiver, you need to look at the function
426
+ to which the lambda is passed: its signature will tell you whether the lambda has a
427
+ receiver and, if it does, what its type is.
428
+ * Using invoke to support flexible DSL syntax
429
+ fun main() {
430
+
431
+ val issues = Issues()
432
+ issues.add("a")
433
+
434
+ issues {
435
+ add("abc")
436
+ } // issues({add("abc")})
437
+ }
438
+
439
+ class Issues(
440
+ val data: MutableList<String > = mutableListOf()
441
+ ) {
442
+ fun add(s: String) {
443
+ data.add(s)
444
+ }
445
+
446
+ operator fun invoke(body: Issues.() -> Unit) {
447
+ body()
448
+ }
449
+ }
400
450
0 commit comments