Я вижу этот код в этом блоге: Программирование на уровне в Scala:
// define the abstract types and bounds
trait Recurse {
type Next <: Recurse
// this is the recursive function definition
type X[R <: Recurse] <: Int
}
// implementation
trait RecurseA extends Recurse {
type Next = RecurseA
// this is the implementation
type X[R <: Recurse] = R#X[R#Next]
}
object Recurse {
// infinite loop
type C = RecurseA#X[RecurseA]
}
В коде R#X[R#Next]
есть оператор #
, который я никогда не видел. Поскольку это трудно найти в нем (игнорируется поисковыми системами), кто может сказать мне, что это значит?
Чтобы объяснить это, сначала нужно объяснить вложенные классы в 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.
Class
- это представление классов Java во время выполнения, и оно ограничено даже в Java. Например, List<String>
и List<Integer>
имеют один и тот же Class
времени выполнения. Если Class
недостаточно богат для представления типов Java , он практически бесполезен при представлении типов Scala . И снова, res7: Class[A#B] = class A$B
, слева от знака равенства - это тип, справа от типа равенства - значение, которое является представлением класса во время выполнения Java.
Он известен как тип проекции и используется для доступа к членам типа.
scala> trait R {
| type A = Int
| }
defined trait R
scala> val x = null.asInstanceOf[R#A]
x: Int = 0
В принципе, это способ обращения к классам внутри других классов.
http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html (поиск по "фунту" )
Здесь ресурс для поиска на "символических операторах" (которые действительно являются методами), но я не понял, как избежать "#" для поиска в scalex)