E220: Default Shadows Given — 기본 인자가 given을 가려버려요

E220: Default Shadows Given — 기본 인자가 given을 가려버려요

암시적 파라미터에 기본 인자(default argument)가 쓰였는데도 스코프에 given 인스턴스가 있는 상황에서 이 경고가 발생해요. using 인자 중 일부만 명시적으로 넘기고 나머지를 비워두면, 그 남은 파라미터는 given 인스턴스를 찾는 대신 기본 인자로 채워집니다. 덕분에 스코프의 given이 무시되는, 의외의 동작이 나올 수 있어요.

출처: Scala 3 Reference

본문

Example

def f(using s: String, i: Int = 1): String = s * i

def example: String =
  given Int = 2
  f(using s = "ab")

여기서 스코프에 given Int = 2가 있는데, i에는 기본 인자 1이 들어가요.

Error

-- [E220] Type Warning: example.scala:5:3 --------------------------------------
5 |  f(using s = "ab")
  |  ^^^^^^^^^^^^^^^^^
  |  Argument for implicit parameter i was supplied using a default argument.
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Usually the given in scope is intended, but you must specify it after explicit `using`.
   -----------------------------------------------------------------------------

Solution

스코프의 given을 쓰고 싶다면 using 키워드 뒤에 명시적으로 지정하면 됩니다.

def f(using s: String, i: Int = 1): String = s * i

def example: String =
  given Int = 2
  f(using s = "ab", i = summon[Int])

파라미터를 별도의 절(clause)로 나누면 given이 제대로 해석돼요.

def g(using s: String)(using i: Int = 1): String = s * i

def example: String =
  given Int = 2
  g(using s = "ab")  // given Int is used from the second clause

의도적으로 기본 인자를 쓰려는 거라면, 기본값을 명시적으로 넘겨 경고를 없앨 수 있어요.

def f(using s: String, i: Int = 1): String = s * i

def example: String =
  given Int = 2
  f(using s = "ab", i = 1)  // explicit default value, no warning