E177: Constructor Proxy Shadows — 생성자 프록시가 가림
E177: Constructor Proxy Shadows — 생성자 프록시가 가림
내부 클래스의 생성자 프록시에 대한 참조가 같은 이름을 가진 외부 참조(메서드나 객체 등)를 가릴 때 발생하는 에러예요.
본문
Scala 3에서는 클래스에 대해 생성자 프록시가 자동 생성되어, new를 쓰지 않고도 인스턴스를 만들 수 있어요. 그런데 내부 클래스가 외부 정의(메서드, 객체, 값)와 이름을 공유하면 컴파일러가 어느 쪽을 의도했는지 판단할 수 없어요.
좀 더 자세한 설명 (Longer explanation)
호출의 의미에 모호함이 있어요:
MyClass(...)
내부 클래스의 인스턴스를 만드는 의미일 수도 있어요:
new MyClass(...)
아니면 같은 이름을 가진 외부 메서드/객체를 호출한다는 의미일 수도 있어요:
MyClass(...)
모호함을 없애려면 전자를 의도한다면 명시적인 new를 쓰고, 후자를 의도한다면 전체 프리픽스를 사용해주세요.
예시 (Example)
object Test:
def MyClass(s: String): String = s
class Outer:
class MyClass(s: String)
val x = MyClass("hello") // ambiguous: inner class or outer method?
에러 (Error)
-- [E177] Reference Error: example.scala:6:12 ----------------------------------
6 | val x = MyClass("hello") // ambiguous: inner class or outer method?
| ^^^^^^^
| Reference to constructor proxy for class MyClass in class Outer
| shadows outer reference to method MyClass in object Test
|
| The instance needs to be created with an explicit `new`.
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| There is an ambiguity in the meaning of the call
|
| MyClass(...)
|
| It could mean creating an instance of class MyClass in class Outer with
|
| new MyClass(...)
|
| Or it could mean calling method MyClass in object Test as in
|
| MyClass(...)
|
| To disambiguate, use an explicit `new` if you mean the former,
| or use a full prefix for MyClass if you mean the latter.
-----------------------------------------------------------------------------
해결 방법 (Solution)
내부 클래스의 인스턴스를 만들고 싶다면 명시적으로 new를 쓰세요:
object Test:
def MyClass(s: String): String = s
class Outer:
class MyClass(s: String)
val x = new MyClass("hello") // explicitly create inner class instance
아니면 전체 프리픽스를 써서 외부 메서드를 호출하세요:
object Test:
def MyClass(s: String): String = s
class Outer:
class MyClass(s: String)
val x = Test.MyClass("hello") // explicitly call outer method
더 알아보기
내부 클래스와 외부 정의가 이름을 공유하면 모호함이 생겨요. 의도에 맞게 new나 전체 프리픽스로 명확히 해주세요.