Чтобы объяснить это, мы сначала должны объяснить вложенные классы в Scala. Рассмотрим этот простой пример:
class A {
class B
def f(b: B) = println("Got my B!")
}
Теперь попробуем что-нибудь с этим:
scala> val a1 = new A
a1: A = A@2fa8ecf4
scala> val a2 = new A
a2: A = A@4bed4c8
scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
found : a1.B
required: a2.B
a2.f(new a1.B)
^
Когда вы объявляете класс внутри другого класса в Scala, вы говорите, что каждый экземпляр этого класса имеет такой подкласс. Другими словами, нет A.B
класса, но есть a1.B
и a2.B
классы, и они разные классы, так как сообщение об ошибке говорит нам выше.
Если вы этого не поняли, найдите типы, зависящие от пути.
Теперь #
это дает вам возможность ссылаться на такие вложенные классы, не ограничивая их конкретным экземпляром. Другими словами, нет A.B
, но есть A#B
, что означает B
вложенный класс любого экземпляра A
.
Мы можем увидеть это в работе, изменив код выше:
class A {
class B
def f(b: B) = println("Got my B!")
def g(b: A#B) = println("Got a B.")
}
И попробуем:
scala> val a1 = new A
a1: A = A@1497b7b1
scala> val a2 = new A
a2: A = A@2607c28c
scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
found : a1.B
required: a2.B
a2.f(new a1.B)
^
scala> a2.g(new a1.B)
Got a B.