web-dev-qa-db-fra.com

Que signifie l'opérateur `# 'dans Scala?

Je vois ce code dans ce blog: Programmation au niveau du type dans 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]
}

Il y a un opérateur # dans le code R#X[R#Next] que je n'ai jamais vu. Puisqu'il est difficile de le rechercher (ignoré par les moteurs de recherche), qui peut me dire ce que cela signifie?

120
Freewind

Pour l'expliquer, nous devons d'abord expliquer les classes imbriquées dans Scala. Considérez cet exemple simple:

class A {
  class B

  def f(b: B) = println("Got my B!")
}

Essayons maintenant quelque chose avec:

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)
                   ^

Lorsque vous déclarez une classe à l'intérieur d'une autre classe dans Scala, vous dites que chaque instance de cette classe a une telle sous-classe. En d'autres termes, il n'y a pas de A.B classe, mais il y a a1.B et a2.B classes, et ce sont différentes classes, comme le message d'erreur nous le dit plus haut.

Si vous ne comprenez pas cela, recherchez les types dépendants du chemin.

Maintenant, # vous permet de vous référer à de telles classes imbriquées sans la restreindre à une instance particulière. En d'autres termes, il n'y a pas de A.B, mais il y'à A#B, ce qui signifie une classe imbriquée B de toute instance de A.

Nous pouvons voir cela au travail en changeant le code ci-dessus:

class A {
  class B

  def f(b: B) = println("Got my B!")
  def g(b: A#B) = println("Got a B.")
}

Et l'essayer:

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.
227
Daniel C. Sobral

Il est connu sous le nom de projection de type et est utilisé pour accéder aux membres de type.

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

scala> val x = null.asInstanceOf[R#A]
x: Int = 0
11
missingfaktor

Fondamentalement, c'est une façon de se référer à des classes dans d'autres classes.

http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html (recherche de "livre")

7
moveaway00

Voici une ressource pour rechercher des "opérateurs symboliques" (qui sont vraiment des méthodes), mais je n'ai pas compris comment échapper à "#" pour rechercher dans scalex)

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

2
Gene T