컴퓨터 언어/kotlin

Inline Functions?

이건욱 2020. 5. 15. 10:46

함수로 일급 함수로 계속해서 넘길때 Function 인스턴스가 계속해서 같이 생성이 됩니다.

 

그래서 그러한 경우에는 inline을 통해서 해결을 할수가 있습니다.

[예시]

@Test
fun main() {
	printHelloWrold {
    	println("HelloWorld")
    }
}


inline fun printHelloWrold(body : () -> Unit) {
	body()
}

따라서 자바로 했을 때 디컴파일된 결과로 비교를 했을때 inline을 썻을때에는 HelloWorld가 main에 포함되어있고 안썼을 경우에는 Function 인스턴스가 계속해서 생기는것을 확인을 할수가 있습니다.

 

inline 적용
---------------------------

public final class ExampleUnitTest {
   @Test
   public final void main() {
      int $i$f$printHelloWrold = false;
      int var3 = false;
      String var4 = "HelloWorld";
      boolean var5 = false;
      System.out.println(var4);
   }

   public final void printHelloWrold(@NotNull Function0 body) {
      int $i$f$printHelloWrold = 0;
      Intrinsics.checkParameterIsNotNull(body, "body");
      body.invoke();
   }
}

inline 적용 안한 상태
-------------

  @Test
   public final void main() {
      this.printHelloWrold((Function0)null.INSTANCE);
   }

   public final void printHelloWrold(@NotNull Function0 body) {
      Intrinsics.checkParameterIsNotNull(body, "body");
      body.invoke();
   }

 

하지만 모든 일급 함수를 inline을 적용을 안하고 싶은 경우에는 다음과 같이 noinline 키워드를 통해 해결할수가 있습니다.

 

    @Test
    fun main() {
        printHelloWrold({
            println("HellWorld1")
        } , {
            println("HellWorld2")
        })
    }


    inline fun printHelloWrold(body : () -> Unit ,noinline body2: () -> Unit) {
        body()
        body2()
    }

이 내용은 자바로 decompile 했을때는 결과가 아래와 같이 나옵니다.

 

noinline 적용을 안한 상태
-----------
@Test
   public final void main() {
      int $i$f$printHelloWrold = false;
      int var3 = false;
      String var4 = "HellWorld1";
      boolean var5 = false;
      System.out.println(var4);
      var3 = false;
      var4 = "HellWorld2";
      var5 = false;
      System.out.println(var4);
   }

   public final void printHelloWrold(@NotNull Function0 body, @NotNull Function0 body2) {
      int $i$f$printHelloWrold = 0;
      Intrinsics.checkParameterIsNotNull(body, "body");
      Intrinsics.checkParameterIsNotNull(body2, "body2");
      body.invoke();
      body2.invoke();
   }


noinline 적용한 상태
------------------
   @Test
   public final void main() {
      Function0 body2$iv = (Function0)null.INSTANCE;
      int $i$f$printHelloWrold = false;
      int var4 = false;
      String var5 = "HellWorld1";
      boolean var6 = false;
      System.out.println(var5);
      body2$iv.invoke();
   }

   public final void printHelloWrold(@NotNull Function0 body, @NotNull Function0 body2) {
      int $i$f$printHelloWrold = 0;
      Intrinsics.checkParameterIsNotNull(body, "body");
      Intrinsics.checkParameterIsNotNull(body2, "body2");
      body.invoke();
      body2.invoke();
   }

위와 같이 적용하면 Function 인스턴스가 body2에 생기는것을 볼수가 있습니다.