E199: Tailrec Nested Call
E199: Tailrec Nested Call
이 경고는 @tailrec 메서드가 인라인되지 않은 내부 정의 안에서 재귀 호출을 포함할 때 발생해요.
본문
꼬리 재귀 최적화는 메서드의 본문에서 직접적으로만 적용될 수 있어요. 내부 def를 통해 이루어지는 재귀 호출은 꼬리 재귀로 검증하거나 최적화할 수 없어요. 이 때문에 깊은 재귀 호출에서 스택 오버플로가 발생할 수 있어요.
예시 (Example)
import scala.annotation.tailrec
@tailrec
def countdown(n: Int): Unit =
def helper(): Unit =
countdown(n - 1) // recursive call from inner def
if n > 0 then helper()
else countdown(n - 1)
에러 (Error)
-- [E199] Syntax Warning: example.scala:6:13 -----------------------------------
6 | countdown(n - 1) // recursive call from inner def
| ^^^^^^^^^^^^^^^^
|The tail recursive def countdown contains a recursive call inside the non-inlined inner def helper
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| Tail recursion is only validated and optimised directly in the definition.
| Any calls to the recursive method via an inner def cannot be validated as
| tail recursive, nor optimised if they are. To enable tail recursion from
| inner calls, mark the inner def as inline.
-----------------------------------------------------------------------------
해결 방법 (Solution)
내부 def를 inline으로 표시해요.
import scala.annotation.tailrec
@tailrec
def countdown(n: Int): Unit =
inline def helper(): Unit =
countdown(n - 1)
if n > 0 then helper()
else countdown(n - 1)
아니면 중첩된 재귀 호출을 피하도록 코드를 재구성해요.
import scala.annotation.tailrec
@tailrec
def countdown(n: Int): Unit =
if n > 0 then countdown(n - 1)