E221: Recurse With Default — 재귀 호출에서 기본 인자를 쓰면 위험해요
E221: Recurse With Default — 재귀 호출에서 기본 인자를 쓰면 위험해요
재귀 호출에서 어떤 파라미터에 기본 인자를 사용하면 이 경고가 발생해요. 기본값은 매번 호출할 때마다 현재 값을 스택 아래로 넘기는 대신 그대로 대입되기 때문에, 의도하지 않은 동작이 나올 수 있어요. 현재 파라미터 값을 넘기려던 걸 잘못해서 기본값에 의존한 것 같은 잠재적 버그를 잡아주는 경고입니다.
이 경고는 -Wrecurse-with-default 컴파일러 플래그로 켭니다.
본문
Example
//> using options -Wrecurse-with-default
def fun(x: Int)(using p: Int, q: Int = 0): Int =
if x <= 0 then p * q
else fun(x - 1)(using p = p + x)
재귀 호출에서 q를 넘기지 않고 기본 인자에 맡겼어요.
Error
-- [E221] Type Warning: example.scala:5:17 -------------------------------------
5 | else fun(x - 1)(using p = p + x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Recursive call used a default argument for parameter q.
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| It's more explicit to pass current or modified arguments in a recursion.
-----------------------------------------------------------------------------
Solution
재귀 호출에서 모든 인자를 명시적으로 넘기세요.
//> using options -Wrecurse-with-default
def fun(x: Int)(using p: Int, q: Int = 0): Int =
if x <= 0 then p * q
else fun(x - 1)(using p = p + x, q = q)
아니면 아예 재귀 함수에서 기본 인자를 쓰지 않는 설계로 바꾸는 것도 방법이에요.
//> using options -Wrecurse-with-default
def fun(x: Int)(using p: Int)(q: Int): Int =
if x <= 0 then p * q
else fun(x - 1)(using p = p + x)(q)