You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: kotlin/scope_function.md
+128
Original file line number
Diff line number
Diff line change
@@ -53,3 +53,131 @@ null의 객체가 아닐 경우
53
53
54
54
- Grouping function calls on an object: `with`
55
55
함수간의 그룹핑 처리
56
+
57
+
58
+
59
+
Distinctions
60
+
Because the scope functions are all quite similar in nature, it's important to understand the differences between them. There are two main differences between each scope function:
61
+
62
+
The way to refer to the context object.
63
+
64
+
Thereturn value.
65
+
66
+
Contextobject:thisor it
67
+
Inside the lambda of a scope function, the context objectis available by a short reference instead of its actual name. Each scope function uses one of two ways to access the context object: as a lambda receiver (this) or as a lambda argument (it). Both provide the same capabilities, so we'll describe the pros and cons of each for different cases and provide recommendations on their use.
68
+
```kotlin
69
+
funmain() {
70
+
val str ="Hello"
71
+
// this
72
+
str.run {
73
+
println("The string's length: $length")
74
+
//println("The string's length: ${this.length}") // does the same
75
+
}
76
+
77
+
// it
78
+
str.let {
79
+
println("The string's length is ${it.length}")
80
+
}
81
+
}
82
+
```
83
+
# this
84
+
run, with, and apply refer to the context object as a lambda receiver - by keyword this. Hence, in their lambdas, the object is available as it would be in ordinary class functions. In most cases, you can omit this when accessing the members of the receiver object, making the code shorter. On the other hand, if this is omitted, it can be hard to distinguish between the receiver members and external objects or functions. So, having the context object as a receiver (this) is recommended for lambdas that mainly operate on the object members: call its functions or assign properties.
85
+
```
86
+
val adam = Person("Adam").apply {
87
+
age = 20 // same as this.age = 20 or adam.age = 20
88
+
city = "London"
89
+
}
90
+
println(adam)
91
+
```
92
+
93
+
# it
94
+
In turn, let and also have the context object as a lambda argument. If the argument name is not specified, the object is accessed by the implicit default name it. it is shorter than this and expressions with it are usually easier for reading. However, when calling the object functions or properties you don't have the object available implicitly like this. Hence, having the context object as it is better when the object is mostly used as an argument in function calls. it is also better if you use multiple variables in the code block.
95
+
```
96
+
fun getRandomInt(): Int {
97
+
return Random.nextInt(100).also {
98
+
writeToLog("getRandomInt() generated value $it")
99
+
}
100
+
}
101
+
102
+
val i = getRandomInt()
103
+
println(i)
104
+
```
105
+
106
+
Additionally, when you pass the context object as an argument, you can provide a custom name for the context object inside the scope.
107
+
```
108
+
fun getRandomInt(): Int {
109
+
return Random.nextInt(100).also { value ->
110
+
writeToLog("getRandomInt() generated value $value")
111
+
}
112
+
}
113
+
114
+
val i = getRandomInt()
115
+
println(i)
116
+
```
117
+
Return value
118
+
The scope functions differ by the result they return:
119
+
120
+
apply and also return the context object.
121
+
122
+
let, run, and with return the lambda result.
123
+
124
+
These two options let you choose the proper function depending on what you do next in your code.
125
+
126
+
Context object
127
+
The return value of apply and also is the context object itself. Hence, they can be included into call chains as side steps: you can continue chaining function calls on the same object after them.
128
+
```
129
+
val numberList = mutableListOf<Double>()
130
+
numberList.also { println("Populating the list") }
131
+
.apply {
132
+
add(2.71)
133
+
add(3.14)
134
+
add(1.0)
135
+
}
136
+
.also { println("Sorting the list") }
137
+
.sort()
138
+
```
139
+
140
+
They also can be used in return statements of functions returning the context object.
141
+
```
142
+
fun getRandomInt(): Int {
143
+
return Random.nextInt(100).also {
144
+
writeToLog("getRandomInt() generated value $it")
145
+
}
146
+
}
147
+
```
148
+
val i = getRandomInt()
149
+
Open in Playground →
150
+
Target platform: JVM
151
+
Running on kotlin v.1.6.10
152
+
Lambda result
153
+
let, run, and with return the lambda result. So, you can use them when assigning the result to a variable, chaining operations on the result, and so on.
154
+
```
155
+
156
+
```kotlin
157
+
val numbers =mutableListOf("one", "two", "three")
158
+
val countEndsWithE = numbers.run {
159
+
add("four")
160
+
add("five")
161
+
count { it.endsWith("e") }
162
+
}
163
+
println("There are $countEndsWithE elements that end with e.")
164
+
OpeninPlayground →
165
+
Target platform:JVM
166
+
Running on kotlin v.1.6.10
167
+
Additionally, you can ignore the return value and use a scope function to create a temporary scope for variables.
168
+
```
169
+
170
+
```kotlin
171
+
val numbers =mutableListOf("one", "two", "three")
172
+
with(numbers) {
173
+
val firstItem = first()
174
+
val lastItem = last()
175
+
println("First item: $firstItem, last item: $lastItem")
176
+
}
177
+
val numbers =mutableListOf("one", "two", "three")
178
+
with(numbers) {
179
+
val firstItem = first()
180
+
val lastItem = last()
181
+
println("First item: $firstItem, last item: $lastItem")
0 commit comments