<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>lily_1115.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 20 Apr 2022 13:00:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>lily_1115.log</title>
            <url>https://velog.velcdn.com/images/lily_1115/profile/50c9bfb7-d849-41cf-a947-5f9d08469fa4/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. lily_1115.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/lily_1115" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[java] 클래스 생성자 호출 순서]]></title>
            <link>https://velog.io/@lily_1115/java-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%98%B8%EC%B6%9C-%EC%88%9C%EC%84%9C</link>
            <guid>https://velog.io/@lily_1115/java-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%98%B8%EC%B6%9C-%EC%88%9C%EC%84%9C</guid>
            <pubDate>Wed, 20 Apr 2022 13:00:58 GMT</pubDate>
            <description><![CDATA[<h3 id="자바-상속의-특징">자바 상속의 특징</h3>
<p>1.자바클래스의 상속은 단일상속이다.</p>
<p>2.상속은(특정 클래스가 가지는 일부 속성과 기능을 다른 클래스에 제공하기위해 맺는 클래스간의 관계이다. )</p>
<p>3.두 클래스를 부모와 자식관계로 맺어주는다.</p>
<p>4.자식은 부모의 요소를 전부 가져온다.(단, 생성자는 제외이다.)</p>
<p>5.조상은 자손에게 영향O , 자손클래스의 변경은 아무런 영향X. </p>
<p>6.상속받지 않은 클래스들은 모두 최상위 클래스 java.lang.Object클래스를 묵시적으로 상속받는다. </p>
<blockquote>
<p>자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자가 호출되지 않으면 자동으로 부모 클래스의 default 생성자가 호출된다.</p>
</blockquote>
<p>자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자를 호출할 수도 있다.</p>
<p>super 키워드를 사용하여 부모 클래스의 생성자를 호출할 수 있는데, 이때 super 키워드는 제일 처음에 호출되어야 한다. 그러지 않으면 &#39;Constructor call must be the first statement in a constructor&#39;라는 오류 문구가 뜬다.</p>
<p>또한 부모 클래스에 디폴트 생성자가 없는 경우도 있는데 그럴 때는 다른 생성자를 반드시 호출해야 한다.</p>
<pre><code class="language-java">package action.java.test;

class Vehicle {
    int speed;

    //삭제시 에러발생 -&gt; superClass가 시그니처 생성자를 만들경우 더이상 default생성자가지고 있다.
    //따라서 default 클래스를 만들어 자동으로 호출하게 하거나
    //시그니처 생성자를 super()로 호출하게 해야한다.
    public Vehicle() {
        System.out.println(&quot;Vehicle()생성&quot;);
    }

    public Vehicle(int speed) {
        super();//상속받지 않은 클래스들은 모두 최상위 클래스 java.lang.Object클래스를 묵시적으로 상속기때문에 생략가능
        this.speed = speed;
        System.out.println(&quot;Vehicle(int) 생성 : speed = &quot; + speed);
    }

}

class Car extends Vehicle {
    int oil;

    public Car() {
        //호출할 상위클래스의 생성자를 직접 명시할 수 있다.
        super(45);
        System.out.println(&quot;Car() 생성&quot;);
    }

    public Car(int oil) {
        super();
        this.oil = oil;
        super(); //super 키워드가 처음에 호출되지 않으면 오류 발생
        System.out.println(&quot;Car(int) 생성 : oil = &quot; + oil);
    }

    public Car(int oil, int speed) {
        super();
        //상위클래스의 생성자를 호출하지 않으면 상위클래스의 기본 생성자가 호출 된다.
        this.oil = oil;
        System.out.println(&quot;Car(int) 생성 : oil = &quot; + oil + &quot; speed = &quot; + speed);
    }

}

public class DefaultConstructor {
    public static void main(String[] args) {
        Vehicle v1 = new Vehicle();
        System.out.println();

        Vehicle v2 = new Vehicle(100);
        System.out.println();

        Car car1 = new Car(100, 60);
        System.out.println();

        Car car2 = new Car();
        System.out.println();

         //정답 유추 해보세요!
        Car car3 = new Car(100, 60);
        System.out.println();

    }

}</code></pre>
<p>Vehicle()생성 </p>
<p>Vehicle(int) 생성 : speed = 100</p>
<p>Vehicle()생성
Car(int) 생성 : oil = 100 speed = 60</p>
<p>Vehicle(int) 생성 : speed = 45
Car() 생성</p>
<p>Vehicle()생성
Car(int) 생성 : oil = 100 speed = 60</p>
<pre><code class="language-java">
class HybridCar extends Car {
    int electricity;

    public HybridCar() {
        System.out.println(&quot;HybridCar() 생성&quot;);
    }

    public HybridCar(int electricity) {
        System.out.println(&quot;HybridCar(int) 생성 : electricity = &quot; + electricity);
        this.electricity = electricity;
    }

    public HybridCar(int electricity, int oil) {
        this(electricity); //생성자 위임, 매개변수가 하나인 본인 클래스의 생성자를 호출함
        System.out.println(&quot;HybridCar(int, int) 생성 : oil = &quot; + oil);
        this.oil = oil;
    }

}

public class DefaultConstructor {
    public static void main(String[] args) {

        //정답 유추 해보세요!
        HybridCar hybridCar1 = new HybridCar();
        System.out.println();

        //정답 유추 해보세요!
        HybridCar hybridCar2 = new HybridCar(120, 800);
    }

}</code></pre>
<p>Vehicle(int) 생성 : speed = 45
Car() 생성
HybridCar() 생성</p>
<p>Vehicle(int) 생성 : speed = 45
Car() 생성
HybridCar(int) 생성 : electricity = 120
HybridCar(int, int) 생성 : oil = 800</p>
<h3 id="참고">참고</h3>
<p><a href="https://jojelly.tistory.com/39">https://jojelly.tistory.com/39</a></p>
<p><a href="https://mimah.tistory.com/entry/Java-%EC%83%81%EC%86%8D-%EA%B4%80%EA%B3%84%EC%97%90%EC%84%9C-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%98%B8%EC%B6%9C-%EC%88%9C%EC%84%9C">https://mimah.tistory.com/entry/Java-%EC%83%81%EC%86%8D-%EA%B4%80%EA%B3%84%EC%97%90%EC%84%9C-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%98%B8%EC%B6%9C-%EC%88%9C%EC%84%9C</a></p>
<p><a href="https://stackoverflow.com/questions/48392818/when-do-superclasses-not-have-a-default-constructor">https://stackoverflow.com/questions/48392818/when-do-superclasses-not-have-a-default-constructor</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[최상위 선언]]></title>
            <link>https://velog.io/@lily_1115/%EC%B5%9C%EC%83%81%EC%9C%84-%EC%84%A0%EC%96%B8</link>
            <guid>https://velog.io/@lily_1115/%EC%B5%9C%EC%83%81%EC%9C%84-%EC%84%A0%EC%96%B8</guid>
            <pubDate>Thu, 14 Apr 2022 14:36:36 GMT</pubDate>
            <description><![CDATA[<p>-수정 중..</p>
<h3 id="utilkt">Util.kt</h3>
<pre><code class="language-kotlin">@file:JvmName(&quot;MyUtil&quot;)
package common // package 선언이 있어야 외부에서 import를 통해 접근가능하다


class TopClass {

}
fun topFunction(){
    print(&quot;top_function&quot;)
}

const val topValue = &quot;topValue&quot;</code></pre>
<h3 id="kotlin">Kotlin</h3>
<pre><code class="language-kotlin">package action.kotlin.test

import common.TopClass
import common.topFunction
import common.topValue

fun test() {
    TopClass()
    topFunction() //java와 달리 클래스 명(최상의 함수 정의한 파일 명).메소드로 접근 안해도 됨
    topValue

}
</code></pre>
<h3 id="java">Java</h3>
<pre><code class="language-java">package action.java.test;
import common.MyUtil;
import common.TopClass;

public class TestTop {
    public static void main(String[] args) {
        MyUtil.topFunction();
        System.out.println(MyUtil.topValue);
        TopClass topClass = new TopClass();

    }

}</code></pre>
<p><a href="https://june0122.tistory.com/9">https://june0122.tistory.com/9</a>
<a href="https://kotlinworld.com/69">https://kotlinworld.com/69</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Override]]></title>
            <link>https://velog.io/@lily_1115/override</link>
            <guid>https://velog.io/@lily_1115/override</guid>
            <pubDate>Thu, 14 Apr 2022 13:00:10 GMT</pubDate>
            <description><![CDATA[<h2 id="override">Override</h2>
<p>자바의 @Override 애노테이션과 비슷한 override 변경자는 상위 클래스나 상위 인터페이스 안에 있는 프로퍼티나 메소드를 오버라이드한다는 표시다. 하지만 자바와 달리 코틀린에서는 override 변경자를 꼭 사용해야 한다. override 변경자는 실수로 상위 클래스의 메소드를 오버라이드하는 경우를 방지해준다. </p>
<h3 id="kotlin">kotlin</h3>
<pre><code class="language-kotlin">internal open class Animal {
    open fun getType(animal: Animal?): String {
        return &quot;animal&quot;
    }
}

internal class Person(private val name: String, private val age: Int) : Animal() {
    fun getType(animal: Animal?): String { // 에러 발생
        return if (animal is Person) {
            &quot;person&quot;
        } else {
            &quot;NA&quot;
        }
    }
}

internal object TestOverride {
    @JvmStatic
    fun main(args: Array&lt;String&gt;) {
        val animal: Animal = Person(&quot;lily&quot;, 26)
        println(animal.getType(animal))
    }
}</code></pre>
<p>컴파일시 아래와 같은 에러가 발생한다.</p>
<blockquote>
<p>Kotlin: &#39;getType&#39; hides member of supertype &#39;Animal&#39; and needs &#39;override&#39; modifier</p>
</blockquote>
<p>override 키워드 명시한 후 빌드한 결과</p>
<blockquote>
<p>person</p>
</blockquote>
<p>*참고 java에서 class 기본 접근제어자는 default이고 kotlin의 internal과 비슷하다.</p>
<h3 id="java">Java</h3>
<pre><code class="language-java">class Animal {
    public String getType(Animal animal) {
        return &quot;animal&quot;;
    }
}

class Person extends Animal {
    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //@Override
    public String getType(Animal animal) {
        if (animal instanceof Person) {
            return &quot;person&quot;;
        } else {
            return &quot;NA&quot;;
        }
    }
}

class TestOverride {
    public static void main(String[] args) {
        Animal animal = new Person(&quot;lily&quot;, 26);
        System.out.println(animal.getType(animal));
    }
}</code></pre>
<blockquote>
<p>person</p>
</blockquote>
<p>자바에서 오버라이드 키워드는 일종의 개발자를 위한 명시일뿐 시그니처(매개변수 Type&amp;개수, 반환Type, 함수이름)이 같은 메소드에대해 실제로 오버라이드를 하지만 @Override 애노테이션이 없어도 컴파일 에러를 발생하지 않는다.</p>
<h4 id="참고">참고</h4>
<p>코틀린 인 액션  4장</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin]스코프 함수]]></title>
            <link>https://velog.io/@lily_1115/Kotlin%EC%8A%A4%EC%BD%94%ED%94%84-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@lily_1115/Kotlin%EC%8A%A4%EC%BD%94%ED%94%84-%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 12 Apr 2022 12:34:34 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/lily_1115/post/ee82010e-ff15-4680-88f6-a72d646c5e1e/image.png" alt="표"></p>
<h2 id="목적">목적</h2>
<ul>
<li><p>Executing a lambda on non-null objects: let</p>
</li>
<li><p>Introducing an expression as a variable in local scope: let</p>
</li>
<li><p>Object configuration: apply</p>
</li>
<li><p>Object configuration and computing the result: run</p>
</li>
<li><p>Running statements where an expression is required: non-extension run</p>
</li>
<li><p>Additional effects: also</p>
</li>
<li><p>Grouping function calls on an object: with</p>
</li>
</ul>
<p>코틀린 스코프 함수는 객체의 context내에서 코드를 실행하는 유일한 목적을 갖고 있습니다
람다식을 갖고있는 객체에대해 이런한 함수를 call할 때, 임시적인 스코프로 형성합니다.스코프 안에서 객체를 객체를 표현하는 이름 없이 접근 할 수 있습니다. 이런 함수를 스코프 함수라 부르고 종류는 5개입니다.</p>
<p>let, run, with, apply, also</p>
<p>기본적으로 함수는 같은 역할을 수행합니다.
: 객체위에 코드 블락을 실행함</p>
<p>다른 점은 이 객체가 블록 내부에서 어떻게 사용 가능하게 되는지와 전체 표현식의 결과가 무엇인지입니다.</p>
<pre><code class="language-kotlin">
Person(&quot;Alice&quot;, 20, &quot;Amsterdam&quot;).let {
    println(it)
    it.moveTo(&quot;London&quot;)
    it.incrementAge()
    println(it)
}</code></pre>
<blockquote>
<p>Person(name=Alice, age=20, city=Amsterdam)
Person(name=Alice, age=21, city=London)</p>
</blockquote>
<p>만약 같은 기능을 let없이 사용한다면 새로운 변수를 만들고 사용 할때 마다 그 이름을 반복해야합니다. </p>
<pre><code class="language-kotlin">val alice = Person(&quot;Alice&quot;, 20, &quot;Amsterdam&quot;)
println(alice)
alice.moveTo(&quot;London&quot;)
alice.incrementAge()
println(alice)</code></pre>
<blockquote>
<p>Person(name=Alice, age=20, city=Amsterdam)
Person(name=Alice, age=21, city=London)</p>
</blockquote>
<p>스코프 함수의 유사한 특성때문에 이들 사이의 주요 차이점을 아는 것이 중요합니다
주요 차이점은 두가지가 있습니다.</p>
<ol>
<li>context 객체를 참조하는 방법</li>
<li>리턴 값</li>
</ol>
<h2 id="context-object-this-or-it">Context Object: this or it</h2>
<p>람다 스코프 함수안에 contex 객체는 그것의 실제 이름을 사용하는 대신에 짧은 참조를 이용될 수 있습니다. 각 스코프 함수는 context object에 접근하는 방법인 두개 중 하나를 사용합니다.
this: 람다 수신자
it : 람다 변수 </p>
<p>각각 같은 기능을 제공합니다. 이제 각각 상황에 대한 장 단점을 설명하고, 그것들을 추천사용법을 알려드리겠습니다.</p>
<pre><code class="language-kotlin">fun main() {
    val str = &quot;Hello&quot;
    // this
    str.run {
        println(&quot;The string&#39;s length: $length&quot;)
        //println(&quot;The string&#39;s length: ${this.length}&quot;) // does the same
    }

    // it
    str.let {
        println(&quot;The string&#39;s length is ${it.length}&quot;)
    }
}</code></pre>
<blockquote>
<p>The string&#39;s length: 5
The string&#39;s length is 5</p>
</blockquote>
<h3 id="this">this</h3>
<p>run, with 그리고 apply는 context this 키워드로 부터 객체를 lamda 수신자로 참조 합니다.
그러므로 람다안에서 객체는 일반 클래스 함수안에서 사용 할 수 있습니다. 
대부분의 경우 수신객체의 멤버에 접근할때 this를 제거할 수 있습니다. 그러나 this는 수신객체와 외부 객체 또는 함수를 구별 하기 어렵습니다. 그래서 context object를 수신객체인 this로 갖는 것은 주로 객체의 멤버를 계산하는 람다식(객체의 함수의 호출, 또는 프로퍼티에 값 할당)에 추천합니다.</p>
<pre><code class="language-kotlin">val adam = Person(&quot;Adam&quot;).apply { 
    age = 20                       // same as this.age = 20 or adam.age = 20
    city = &quot;London&quot;
}
println(adam)</code></pre>
<blockquote>
<p>Person(name=Adam, age=20, city=London)</p>
</blockquote>
<pre><code class="language-kotlin">    data class Apple(var weight: Int)
        class AppleTree(val appleTree: List&lt;Apple&gt;) {
            fun pick(): Apple {
                return appleTree[0]
            }
        }
//여기서 apply를 사용하는 경우 this는 가려지게 되고 this.weight은 fruteBasket이 아닌 apple을 참조한다.
        class FruitBasket {
            private var weight = 0

            fun addFrom(appleTree: AppleTree) {
                val apple = appleTree.pick().let { it -&gt;
                    this.weight += it.weight
                    add(it)
                }

            }

            fun add(apple: Apple) {

            }
        }</code></pre>
<h3 id="it">it</h3>
<p>결국 let, also는 context 객체를 lamda 변수로 갖습니다. 만약 변수이름이 명시되지 않았다면, 객체는 암시적 기본 이름인 it으로 접근할 수 있습니다.
it은 this보다 더 짧고 it을 갖을 표현은 읽기 편합니다. 하지만 객체의 함수나 프로퍼티들을 호출할 때 this처럼 암시적으로 이용할 수 있는 객체가 없습니다. 그러나 context 객체를 it으로 갖는 것은 객체가 함수 호출 안에서 변수로 사용될때 더 좋 습니다. it은 또한 코드 블록의 다양한 변수를 사용할때 더 좋습니다.</p>
<pre><code class="language-kotlin">fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog(&quot;getRandomInt() generated value $it&quot;)
    }
}

val i = getRandomInt()
println(i)</code></pre>
<blockquote>
<p>INFO: getRandomInt() generated value 99
99</p>
</blockquote>
<p>추가적으로 context obejct를 변수로 전달할때 스코프 안에서 context object의 custom name을 전달 할 수 있습니다.</p>
<pre><code class="language-kotlin">fun getRandomInt(): Int {
    return Random.nextInt(100).also { value -&gt;
        writeToLog(&quot;getRandomInt() generated value $value&quot;)
    }
}

val i = getRandomInt()
println(i)</code></pre>
<h2 id="return-value">return value</h2>
<p>스코프 함수는 리턴되는 값에 따라 다릅니다</p>
<ol>
<li>apply, also는 context 객체를 리턴</li>
<li>let, run, 그리고 with은 lamda의 결과를 리턴</li>
</ol>
<h3 id="context-obejct">Context Obejct</h3>
<p>apply와 also는 자기자신의 context 객체를 리턴합니다. 그러므로 그것은 call chain에 사이드 스텝으로써 포함될 수 있습니다: 함수 호출 후 동일한 개체에 대한 함수 호출을 계속할 수 있습니다.</p>
<pre><code class="language-kotlin">val numberList = mutableListOf&lt;Double&gt;()
numberList.also { println(&quot;Populating the list&quot;) }
    .apply {
        add(2.71)
        add(3.14)
        add(1.0)
    }
    .also { println(&quot;Sorting the list&quot;) }
    .sort()</code></pre>
<p>또한 context 객체를 리턴하는 함수의 문으로 사용될 수 있습니다.</p>
<pre><code class="language-kotlin">fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog(&quot;getRandomInt() generated value $it&quot;)
    }
}

val i = getRandomInt()</code></pre>
<blockquote>
<p>INFO: getRandomInt() generated value 55</p>
</blockquote>
<h3 id="lamda-result">Lamda result</h3>
<p>let, run, and with은 람다 결과를 반환합니다. 따라서 변수에 결과를 할당하거나 결과에 대한 연산을 연결하는 등의 작업을 수행할 때 사용할 수 있습니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
val countEndsWithE = numbers.run { 
    add(&quot;four&quot;)
    add(&quot;five&quot;)
    count { it.endsWith(&quot;e&quot;) }
}
println(&quot;There are $countEndsWithE elements that end with e.&quot;)</code></pre>
<blockquote>
<p>There are 3 elements that end with e.</p>
</blockquote>
<p>추가적으로 리턴 값을 무시하거나 변수에대한 임시적인 스코프를 갖는 스코프 함수를 사용할때 사용합니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
with(numbers) {
    val firstItem = first()
    val lastItem = last()        
    println(&quot;First item: $firstItem, last item: $lastItem&quot;)
}</code></pre>
<blockquote>
<p>First item: one, last item: three</p>
</blockquote>
<h2 id="funtion">Funtion</h2>
<p>일반적이 사용 스타일을 정의하는 규칙을 아래 예제에서 확인 가능 합니다</p>
<h3 id="let">let</h3>
<p>호출 체인의 결과에 대해 하나 이상의 함수를 호출할 수 있습니다. 예를 들어, 다음 코드는 컬렉션에 대한 두 가지 작업의 결과를 출력 합니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;)
val resultList = numbers.map { it.length }.filter { it &gt; 3 }
println(resultList)</code></pre>
<blockquote>
<p>[5, 4, 4]</p>
</blockquote>
<p>let 사용 시 </p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;)
numbers.map { it.length }.filter { it &gt; 3 }.let { 
    println(it)
    // and more function calls if needed
} </code></pre>
<blockquote>
<p>[5, 4, 4]</p>
</blockquote>
<p>null 검사에도 사용합니다 </p>
<pre><code class="language-kotlin">val str: String? = &quot;Hello&quot;   
//processNonNullString(str)       // compilation error: str can be null
val length = str?.let { 
    println(&quot;let() called on $it&quot;)        
    processNonNullString(it)      // OK: &#39;it&#39; is not null inside &#39;?.let { }&#39;
    it.length
}</code></pre>
<blockquote>
<p>let() called on Hello</p>
</blockquote>
<p>또한 코드 가독성을 높이기 위해서 제한된 범위의 로컬변수로도 사용합니다. 이를 위해서는 it대신 lambda 변수 이름으로 제공해야 합니다.</p>
<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;
    println(&quot;The first item of the list is &#39;$firstItem&#39;&quot;)
    if (firstItem.length &gt;= 5) firstItem else &quot;!&quot; + firstItem + &quot;!&quot;
}.uppercase()
println(&quot;First item after modifications: &#39;$modifiedFirstItem&#39;&quot;)</code></pre>
<blockquote>
<p>The first item of the list is &#39;one&#39;
First item after modifications: &#39;!ONE!&#39;</p>
</blockquote>
<h3 id="with">with</h3>
<p>비확장 함수 : context 객체는 인수로 전달되지만 lambda 내부에 수신기로 사용할 수있습니다. 반환 값은 lambda 결과 입니다. 람다 결과를 제공하지 않고 컨텍스트 객체의 함수, 프로퍼티를 호출하려면 사용하는 것이 좋습니다. 코드에서는 &quot;이 개체를 사용하여 다음을 수행합니다&quot;로 읽습니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
with(numbers) {
    println(&quot;&#39;with&#39; is called with argument $this&quot;)
    println(&quot;It contains $size elements&quot;)
}</code></pre>
<blockquote>
<p>&#39;with&#39; is called with argument [one, two, three]
It contains 3 elements</p>
</blockquote>
<p>또 다른 사용 사례는 값을 계산하는 데 사용할 프로퍼티 또는 함수를 사용하는 도우미 개체를 도입하는 것입니다.</p>
<pre><code class="language-kotlin">val numbers = mutableListOf(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
val firstAndLast = with(numbers) {
    &quot;The first element is ${first()},&quot; +
    &quot; the last element is ${last()}&quot;
}
println(firstAndLast)</code></pre>
<blockquote>
<p>The first element is one, the last element is three</p>
</blockquote>
<h3 id="run">run</h3>
<p>컨텍스트 객체를 lambda 수신기로 사용할 수 있습니다. 반환 값은 람다 결과입니다. 실행은 let과 동일한 기능을 수행하지만 컨텍스트 개체의 확장 함수로 let을 호출합니다.(추가적인 연산을 진행하고 그값을 반환하는..) run은 람다에 객체 초기화 및 반환값 계산이 모두 포함되어 있는 경우에 유용합니다.</p>
<pre><code class="language-kotlin">val service = MultiportService(&quot;https://example.kotlinlang.org&quot;, 80)

val result = service.run {
    port = 8080
    query(prepareRequest() + &quot; to port $port&quot;)
}

// the same code written with let() function:
val letResult = service.let {
    it.port = 8080
    it.query(it.prepareRequest() + &quot; to port ${it.port}&quot;)
}</code></pre>
<blockquote>
<p>Result for query &#39;Default request to port 8080&#39;
Result for query &#39;Default request to port 8080&#39;</p>
</blockquote>
<p>확장자가 아닌 함수로 사용할 수 있습니다. 비확장 실행을 사용하면 식이 필요한 경우 여러 문의 블록을 실행할 수 있습니다.</p>
<pre><code class="language-kotlin">val hexNumberRegex = run {
    val digits = &quot;0-9&quot;
    val hexDigits = &quot;A-Fa-f&quot;
    val sign = &quot;+-&quot;

    Regex(&quot;[$sign]?[$digits$hexDigits]+&quot;)
}

for (match in hexNumberRegex.findAll(&quot;+123 -FFFF !%*&amp; 88 XYZ&quot;)) {
    println(match.value)
}</code></pre>
<blockquote>
<p>+123
-FFFF
88</p>
</blockquote>
<h3 id="apply">apply</h3>
<p>값을 반환하지 않고 주로 수신기 객체의 멤버에서 작동하는 코드 블록에 대해 apply를 사용합니다. 일반적인 경우는 객체 구성입니다. 이러한 호출은 &quot;객체에 다음 할당을 적용&quot;으로 읽을 수 있습니다. 또한 chaing도 적용할 수 있습니다.</p>
<pre><code class="language-kotlin">val adam = Person(&quot;Adam&quot;).apply {
    age = 32
    city = &quot;London&quot;        
}
println(adam)</code></pre>
<blockquote>
<p>Person(name=Adam, age=32, city=London)</p>
</blockquote>
<h3 id="also">also</h3>
<p>객체를 인수로 사용하고 객체를 반환 합니다. 객체의 속성 및 기능 대신 참조 객체의 참조가 필요한 작업이나 외부 범위에서 this에 의해 가려지지 않을려면 사용합니다. 코드에서도 &quot;객체에 대해 다음 작업을 수행할 수도 있습니다.&quot;라고 읽을 수 있습니다.</p>
<pre><code class="language-kotlin">l 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>
<blockquote>
<p>The list elements before adding new one: [one, two, three]</p>
</blockquote>
<h2 id="참고">참고</h2>
<p><a href="https://kotlinlang.org/docs/scope-functions.html#function-selection">https://kotlinlang.org/docs/scope-functions.html#function-selection</a></p>
]]></description>
        </item>
    </channel>
</rss>