Что означает оператор # в Scala?

106

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

  • 1
    «знак фунта» иногда называют «октатропом» (поиск в Google привел меня на эту страницу).
  • 3
    Сделайте этот октоторп или октоторп
Показать ещё 1 комментарий
Теги:
type-systems

4 ответа

196
Лучший ответ

Чтобы объяснить это, сначала нужно объяснить вложенные классы в 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.
  • 0
    Отличный пример. Я полностью согласен с тем, что это работает таким образом, но трудно понять это: scala> classOf [A # B] res7: Class [A # B] = класс A $ B scala> classOf [aB] res8: Class [aB] = класс A $ B. что означает, что они на самом деле имеют один и тот же тип?
  • 2
    Их значения имеют одинаковое строковое представление - и они могут даже быть равными. Class - это представление классов Java во время выполнения, и оно ограничено даже в Java. Например, List<String> и List<Integer> имеют один и тот же Class времени выполнения. Если Class недостаточно богат для представления типов Java , он практически бесполезен при представлении типов Scala . И снова, res7: Class[A#B] = class A$B , слева от знака равенства - это тип, справа от типа равенства - значение, которое является представлением класса во время выполнения Java.
9

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

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

scala> val x = null.asInstanceOf[R#A]
x: Int = 0
  • 5
    Это не ответ. Он в основном показывает тот же код, что и вопрос, только немного сокращенный. В чем, например, разница в обозначении точки? Где бы я использовал этот # в реальном коде?
  • 2
    @ notan3xit, возможно, это не ответ на то, что вы хотели спросить. Но то, что вы спросили: «... что я никогда не видел. Так как это трудно найти (игнорируется поисковыми системами), кто может сказать мне, что это значит?»
7

В принципе, это способ обращения к классам внутри других классов.

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

1

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню