๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Kotlin] ๋žŒ๋‹ค๋Š” ์ž๋ฐ”๋กœ ์–ด๋–ป๊ฒŒ ์ปดํŒŒ์ผ๋ ๊นŒ

1. ๋ฐ›๋Š” ์ธ์ˆ˜๊ฐ€ ์—†๊ณ , ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ์—†๋Š” ๋žŒ๋‹ค

์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ

fun runLambda(lambda: () -> Unit) {
    lambda()
}

fun main() {
    runLambda { println("HelloWord") }
}

// ์ถœ๋ ฅ ๊ฒฐ๊ณผ : HelloWord

 

์ž๋ฐ” ๋ณ€ํ™˜

public final class MainKt {
   public static final void main() {
      runLambda((Function0)null.INSTANCE);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void runLambda(@NotNull Function0 lambda) {
      Intrinsics.checkNotNullParameter(lambda, "lambda");
      lambda.invoke();
   }
}

 

 

๋ฐ›๋Š” ์ธ์ˆ˜๊ฐ€ ์—†๊ณ , ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ์—†๋Š” ๋žŒ๋‹ค๋Š” Function0 ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ตฌํ˜„๋œ ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

 

Function0 ์ธํ„ฐํŽ˜์ด์Šค

// Functions.kt ์•ˆ
package kotlin.jvm.functions

/** A function that takes 0 arguments. */
public interface Function0<out R> : Function<R> {
    /** Invokes the function. */
    public operator fun invoke(): R
}

 

2 ์™ธ๋ถ€ ์Šค์ฝ”ํ”„์—  value ์ฐธ์กฐํ•˜๋Š” ๋žŒ๋‹ค

์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ

fun runLambda(lambda: () -> Unit) {
    lambda()
}

fun main() {
    val sayHello = "Say Hello"
    runLambda {
        println(sayHello)
    }
}

// ์ถœ๋ ฅ ๊ฒฐ๊ณผ : Say Hello

 

์ž๋ฐ” ๋ณ€ํ™˜

public final class MainKt {
   public static final void main() {
      final String sayHello = "Say Hello";
      runLambda((Function0)(new Function0() {
         // $FF: synthetic method
         // $FF: bridge method
         public Object invoke() {
            this.invoke();
            return Unit.INSTANCE;
         }

         public final void invoke() {
            String var1 = sayHello;
            System.out.println(var1);
         }
      }));
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void runLambda(@NotNull Function0 lambda) {
      Intrinsics.checkNotNullParameter(lambda, "lambda");
      lambda.invoke();
   }
}

 

value์˜ ์ฐธ์กฐ๋ฅผ Function0 ํด๋ž˜์Šค ์•ˆ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

2 ์™ธ๋ถ€ ์Šค์ฝ”ํ”„์—  variable์„ ์ฐธ์กฐํ•˜๋Š” ๋žŒ๋‹ค

์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ

fun main() {
    var sayHi = "Say Hi"
    val myLambda = {
        println(sayHi)
    }
    sayHi = "Good night"
    myLambda()
}

//์ถœ๋ ฅ ๊ฒฐ๊ณผ : Good night

 

์ž๋ฐ” ๋ณ€ํ™˜

public final class MainKt {
   public static final void main() {
      final Ref.ObjectRef sayHi = new Ref.ObjectRef();
      sayHi.element = "Say Hi";
      Function0 myLambda = (Function0)(new Function0() {
         // $FF: synthetic method
         // $FF: bridge method
         public Object invoke() {
            this.invoke();
            return Unit.INSTANCE;
         }

         public final void invoke() {
            String var1 = (String)sayHi.element;
            System.out.println(var1);
         }
      });
      sayHi.element = "Good night";
      myLambda.invoke();
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
}

 

variable์„ Ref ํด๋ž˜์Šค๋กœ ๋ž˜ํ•‘ํ•œ๋‹ค.

variable์ด String์ด๋ฏ€๋กœ, Ref.ObjectRef ํด๋ž˜์Šค์˜ element ๊ฐ’์œผ๋กœ variable์ด ์ €์žฅ๋˜์–ด ๋ž˜ํ•‘๋œ๋‹ค.

๋žŒ๋‹ค ๋ฐ”๊นฅ์˜ varialbe์„ ์บก์ณํ•œ ๋žŒ๋‹ค๊ฐ€ ๋จผ์ € ์„ ์–ธ๋˜์–ด ์žˆ์–ด๋„, ๋žŒ๋‹ค ์‹คํ–‰ ์ „์—ฅ variable์ด ์ˆ˜์ •๋˜๋ฉด Ref.ObjectRef ํด๋ž˜์Šค์˜ element๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์„œ ๋žŒ๋‹ค ์‹คํ–‰ ์‹œ ๋ณ€๊ฒฝ๋œ ๊ฐ’์ด ์ถœ๋ ฅ๋œ๋‹ค.

 

Ref ํด๋ž˜์Šค

//Ref.java ํŒŒ์ผ ์•ˆ

package kotlin.jvm.internal;

import java.io.Serializable;

public class Ref {
    private Ref() {}

    public static final class ObjectRef<T> implements Serializable {
        public T element;

        @Override
        public String toString() {
            return String.valueOf(element);
        }
    }

    public static final class ByteRef implements Serializable {
        public byte element;

        @Override
        public String toString() {
            return String.valueOf(element);
        }
    }
    ... // Short, Long, Int, Boolean, Double, Float, Char์šฉ ๋ž˜ํผ ํด๋ž˜์Šค๋“ค์ด ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค.
}

 

 

3 ์ธ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๋žŒ๋‹ค, ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ์žˆ๋Š” ๋žŒ๋‹ค ๋“ฑ

์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ

fun main() {

    val lambdaWithParameterOne = { it: String ->
        println("lambdaWithParameterOne $it")
    }
    lambdaWithParameterOne("Hello Kotlin")

    val lambdaWithParameterTwo = { one: String, two: String ->
        println("lambdaWithParameterTwo $one, $two")
    }
    lambdaWithParameterTwo("Hi", "Good Luck")

    val lambdaWithReturn = {
        "Return Hello"
    }
    println(
        lambdaWithReturn()
    )

    val lambdaWithParameterAndReturn = { it: String ->
        "$it Kotlin"
    }
    println(
        lambdaWithParameterAndReturn("Hi")
    )
}
// ์ถœ๋ ฅ ๊ฒฐ๊ณผ : 
// lambdaWithParameterOne Hello Kotlin
// lambdaWithParameterTwo Hi, Good Luck
// Return Hello
// Hi Kotlin

 

์ž๋ฐ” ๋ณ€ํ™˜

public final class MainKt {
   public static final void main() {
      Function1 lambdaWithParameterOne = (Function1)null.INSTANCE;
      lambdaWithParameterOne.invoke("Hello Kotlin");
      
      Function2 lambdaWithParameterTwo = (Function2)null.INSTANCE;
      lambdaWithParameterTwo.invoke("Hi", "Good Luck");
      
      Function0 lambdaWithReturn = (Function0)null.INSTANCE;
      Object var3 = lambdaWithReturn.invoke();
      System.out.println(var3);
      
      Function1 lambdaWithParameterAndReturn = (Function1)null.INSTANCE;
      Object var4 = lambdaWithParameterAndReturn.invoke("Hi");
      System.out.println(var4);
   }
}

 

์ธ์ˆ˜๊ฐ€ ํ•œ ๊ฐœ์ด๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๋žŒ๋‹ค -> Function1 ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

์ธ์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ด๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๋žŒ๋‹ค -> Function2 ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

์ธ์ˆ˜๊ฐ€ ์—†๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์ด ์žˆ๋Š” ๋žŒ๋‹ค -> Functoin0 ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

์ธ์ˆ˜๊ฐ€ ํ•œ ๊ฐœ์— ๋ฐ˜ํ™˜ ๊ฐ’์ด ์žˆ๋Š” ๋žŒ๋‹ค -> Function1() ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

 

Functions.kt ํŒŒ์ผ ์•ˆ

/*
 * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

// Auto-generated file. DO NOT EDIT!

package kotlin.jvm.functions

/** A function that takes 0 arguments. */
public interface Function0<out R> : Function<R> {
    /** Invokes the function. */
    public operator fun invoke(): R
}

/** A function that takes 1 argument. */
public interface Function1<in P1, out R> : Function<R> {
    /** Invokes the function with the specified argument. */
    public operator fun invoke(p1: P1): R
}

/** A function that takes 2 arguments. */
public interface Function2<in P1, in P2, out R> : Function<R> {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2): R
}

/** A function that takes 3 arguments. */
public interface Function3<in P1, in P2, in P3, out R> : Function<R> {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3): R
}

...

/** A function that takes 22 arguments. */
public interface Function22<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, in P21, in P22, out R> : Function<R> {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R
}