<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jihye__han.log</title>
        <link>https://velog.io/</link>
        <description>🛹</description>
        <lastBuildDate>Wed, 30 Mar 2022 15:47:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jihye__han.log</title>
            <url>https://images.velog.io/images/jihye__han/profile/69e1af00-33a1-4936-b546-6eded97b1fa7/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jihye__han.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jihye__han" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Kotlin Scope-function 알고 쓰기]]></title>
            <link>https://velog.io/@jihye__han/Kotlin-Scope-function-%EC%95%8C%EA%B3%A0-%EC%93%B0%EA%B8%B0</link>
            <guid>https://velog.io/@jihye__han/Kotlin-Scope-function-%EC%95%8C%EA%B3%A0-%EC%93%B0%EA%B8%B0</guid>
            <pubDate>Wed, 30 Mar 2022 15:47:06 GMT</pubDate>
            <description><![CDATA[<p>코틀린 표준 라이브러리로 확장함수(extension function)들을 제공합니다.
확장함수에는 범위지정함수(scope-functions) 인 <code>apply</code>, <code>also</code>, <code>with</code>, <code>run</code>, <code>let</code> 이 있고, 언제 사용하면 좋을지 &amp; 저는 어떻게 사용하는지 공유해봅니다.</p>
<hr>
<h3 id="apply">apply</h3>
<p>블록 내에서 수신객체를 <code>this</code> 로 사용되고, 수신객체 자신을 리턴합니다.</p>
<pre><code class="language-kotlin">inline fun &lt;T&gt; T.apply(block: T.() -&gt; Unit): T {
    block()
    return this
}</code></pre>
<p>주로 객체를 초기화 할 때 사용하고 있습니다.</p>
<pre><code class="language-kotlin">data class Person(
    var name: String, 
    var age: Int = 0, 
    var city: String = &quot;&quot;
)

val adam = Person(&quot;Adam&quot;).apply {
    age = 32
    city = &quot;London&quot;        
}
println(adam)</code></pre>
<hr>
<h3 id="also">also</h3>
<p>블록 내에서 수신객체를 <code>it</code> 으로 사용할 수 있고, 수신객체 자신을 리턴합니다.</p>
<pre><code class="language-kotlin">inline fun &lt;T&gt; T.apply(block: T.() -&gt; Unit): T {
    block()
    return this
}</code></pre>
<p>Debug나 Log와 같이 수신객체의 속성을 변경하지 않고 참조로 사용할 경우에 유용합니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
numbers
    .also { println(&quot;The list elements before adding new one: $it&quot;) }
    .add(&quot;four&quot;)</code></pre>
<hr>
<h3 id="with">with</h3>
<p>non-nullable 한 수신객체를 블록 내에서 <code>this</code> 로 사용할 수 있고, 람다의 결과를 리턴합니다.</p>
<pre><code class="language-kotlin">inline fun &lt;T, R&gt; with(receiver: T, block: T.() -&gt; R): R {
    return receiver.block()
}</code></pre>
<p>중복되는 객체를 호출할 때 사용하면 코드를 간결하게 만들 수 있습니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)

// 사용 전
println(&quot;&#39;with&#39; is called with argument $numbers&quot;)
println(&quot;It contains ${numbers.size} elements&quot;)

// 사용 후
with(numbers) {
    println(&quot;&#39;with&#39; is called with argument $this&quot;)
    println(&quot;It contains $size elements&quot;)
}</code></pre>
<p>또한, 블록 내의 결과를 반환할 때에도 사용할 수 있습니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)

// 사용 전
val firstAndLast = &quot;The first element is ${numbers.first()},&quot; +
    &quot; the last element is ${numbers.last()}&quot;

// 사용 후
val firstAndLast = with(numbers) {
    &quot;The first element is ${first()},&quot; +
    &quot; the last element is ${last()}&quot;
}
println(firstAndLast)    
// &quot;The first element is one, the last element is three&quot;</code></pre>
<hr>
<h3 id="run">run</h3>
<p>블록 내에서 수신객체를 <code>this</code> 로 사용되고, 람다의 결과를 리턴합니다.</p>
<pre><code class="language-kotlin">inline fun &lt;T, R&gt; T.run(block: T.() -&gt; R): R {
    return block()
}</code></pre>
<p>with 와 비슷하지만 사용하는 방식에 차이가 있습니다.
수신객체를 이용하여 어떠한 계산된 결과를 리턴하고자 할 때에 사용할 수 있습니다.</p>
<pre><code class="language-kotlin">val p1 = Person(&quot;Jihye&quot;, 27, &quot;Seoul&quot;)
val p2 = Person(&quot;Adam&quot;, 32, &quot;London&quot;)

val isSeoul: Boolean = p1.run {
    this.city == &quot;Busan&quot;    // 결과를 리턴합니다.
}
println(isSeoul)    // false

val sumAge: Boolean = run {
    p1.age + p2.age
}
println(sumAge)    // 59</code></pre>
<hr>
<h3 id="let">let</h3>
<p>블록 내에서 수신객체를 <code>it</code> 으로 사용할 수 있고, 람다의 결과를 리턴합니다.</p>
<pre><code class="language-kotlin">inline fun &lt;T, R&gt; T.let(block: (T) -&gt; R): R {
    return block(this)
}</code></pre>
<p>nullable 객체를 null이 아닌 경우에 코드를 실행해야 하는 경우 또는 가독성을 위해서도 주로 사용합니다.</p>
<pre><code class="language-kotlin">val str: String? = &quot;Hello&quot;
val length = str?.let { 
    // str이 null이 아닌 경우 처리할 구문
    println(&quot;let() called on $it&quot;)        
    it.length
}</code></pre>
<pre><code class="language-kotlin">val numbers = listOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;)
// 가독성을 위해 
val modifiedFirstItem = numbers.first().let { firstItem -&gt;
    if (firstItem.length &gt;= 5)  firstItem 
    else  &quot;!&quot; + firstItem + &quot;!&quot;
}.uppercase()
println(&quot;First item after modifications: &#39;$modifiedFirstItem&#39;&quot;)

// 만약 let을 사용하지 않았다면?
val modifiedFirstItem = {
    if (numbers.first().length &gt;= 5)  numbers.first() 
    else  &quot;!&quot; + numbers.first() + &quot;!&quot;
}
modifiedFirstItem.uppercase()</code></pre>
<hr>
<h3 id="span-stylecolorindianred주의해야-할-점span"><span style="color:indianred">주의해야 할 점</span></h3>
<p>수신 객체를 블록 내에서 <code>this</code>로 사용하는 <code>apply</code>, <code>run</code>, <code>with</code>은 중첩되어 사용하지 않습니다. 수신객체의 이름도 변경할 수 없는 함수들이기 때문에 중첩되어 사용할 경우 어떤 수신객체를 사용되는지 확인하기 어렵습니다.</p>
<p><code>also</code> 와 <code>let</code> 는 중첩해서 사용할 경우 <code>it</code>을 사용하지 않고 명시적인 이름을 제공하여 이름이 혼동되지 않도록 합니다.</p>
<h3 id="span-stylecolorgray참조span"><span style="color:gray">참조</span></h3>
<ul>
<li><a href="https://medium.com/@limgyumin/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%9D%98-apply-with-let-also-run-%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-4a517292df29">코틀린 의 apply, with, let, also, run 은 언제 사용하는가?</a></li>
<li><a href="https://kotlinlang.org/docs/scope-functions.html">Scope functions</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>