Что означает оператор # в Scala? - PullRequest
118 голосов
/ 25 февраля 2012

Я вижу этот код в этом блоге: Программирование на уровне типов в 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] есть оператор #, который у меня естьникогда не видел.Поскольку его трудно найти (игнорируется поисковыми системами), кто может сказать мне, что это значит?

Ответы [ 4 ]

222 голосов
/ 25 февраля 2012

Чтобы объяснить это, мы сначала должны объяснить вложенные классы в 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.
11 голосов
/ 25 февраля 2012

Он известен как проекция типа и используется для доступа к членам типа.

scala> trait R {
     |   type A = Int
     | }
defined trait R

scala> val x = null.asInstanceOf[R#A]
x: Int = 0
7 голосов
/ 25 февраля 2012

По сути, это способ ссылки на классы в других классах.

http://jim -mcbeath.blogspot.com / 2008/09 / scala-syntax-primer.html (поиск по «фунту»)

2 голосов
/ 27 февраля 2012

Вот ресурс для поиска по «символическим операторам» (которые на самом деле являются методами), но я не понял, как избежать «#» для поиска в scalex)

http://www.artima.com/pins1ed/book-index.html#indexanchor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...