모호한 오버로드

모호한 오버로드 (Ambiguous Overload)

주어진 인자에 일치하는 오버로드된 메서드가 여러 개라서 컴파일러가 어느 것을 호출할지 결정하지 못할 때 나오는 에러예요.

출처: Scala 3 Reference

본문

주어진 인자에 일치하는 오버로드된 메서드가 여러 개 있고, 컴파일러가 어느 하나를 고르지 못할 때 이 에러가 발생해요.

컴파일러가 기대 타입(expected type)을 너무 모르기 때문에 참조할 수 있는 메서드가 여러 개 존재하게 돼요. 기대 타입을 다음과 같이 명시해 주면 돼요.

  • 결과를 타입이 지정된 값에 할당하기
  • instance.myMethod: String => Int 처럼 타입 지정(ascription) 추가하기

예시

object Render:
  extension [A](a: A) def render: String = "Hi"
  extension [B](b: B) def render(using DummyImplicit): Char = 'x'

def example = Render.render(42)

에러 메시지

-- [E051] Reference Error: example.scala:5:21 ----------------------------------
5 |def example = Render.render(42)
  |              ^^^^^^^^^^^^^
  |Ambiguous overload. The overloaded alternatives of method render in object Render with types
  | [B](b: B)(using x$2: DummyImplicit): Char
  | [A](a: A): String
  |both match arguments ((42 : Int))
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | There are 2 methods that could be referenced as the compiler knows too little
  | about the expected type.
  | You may specify the expected type e.g. by
  | - assigning it to a value with a specified type, or
  | - adding a type ascription as in instance.myMethod: String => Int
   -----------------------------------------------------------------------------

해결 방법

// Hint compiler using explicit argument or result type
object Render:
  extension [A](a: A) def render: String = "Hi"
  extension [B](b: B) def render(using DummyImplicit): Char = 'x'

def example: String = Render.render(42)
// Or try to remove methods that might lead to amibgious results
import scala.annotation.targetName
object Render:
  extension [A](a: A) def render: String = "Hi"
  extension [B](b: B) @targetName("render") def renderChar(using DummyImplicit): Char = 'x'

def example = Render.render(42)

더 알아보기

  • 명시적인 인자 타입이나 결과 타입으로 컴파일러에 힌트를 주면 모호함이 풀려요.
  • 모호함을 만들 수 있는 메서드들을 정리하거나 @targetName 으로 이름을 구분해도 돼요.