42 votes

<: <opérateur en scala

Quelqu'un peut-il fournir des détails sur l'opérateur <:< en scala. Je pense:

 if(apple <:< fruit)  //checks if apple is a subclass of fruit.
 

Y a-t-il d'autres explications? Je vois beaucoup de définitions dans le fichier source scala.

33voto

Ben Lings Points 11395

L' <:< type est défini dans Predef.scala avec les types d' =:= et <%< comme suit:

// used, for example, in the encoding of generalized constraints
// we need a new type constructor `<:<` and evidence `conforms`, as 
// reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred)
// to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters)
// simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`)
// in part contributed by Jason Zaugg
sealed abstract class <:<[-From, +To] extends (From => To)
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} // not in the <:< companion object because it is also intended to subsume identity (which is no longer implicit)

Il utilise la Scala disposent que d'un type générique op[T1, T2] peuvent être écrites T1 op T2. Ceci peut être utilisé, comme l'a noté aioobe, de fournir une preuve de paramètres pour les méthodes qui s'appliquent uniquement à certaines instances d'un type générique (l'exemple donné est le toMap méthode qui peut être utilisée uniquement sur un Traversable de Tuple2). Comme l'indique le commentaire, ce généralise un normal générique type de contrainte pour lui permettre de se référer à toute la portée de la vérification type abstrait/type de paramètre. L'utilisation de ce (implicit ev : T1 <:< T2) a l'avantage par rapport à la simple utilisation d'un paramètre de preuve comme (implicit ev: T1 => T2) en ce que cette dernière peut conduire à des de la portée des valeurs implicites utilisés pour la conversion.

Je suis sûr que j'en avais vu quelques discussions sur ce, sur un seul de la Scala de listes de diffusion, mais ne peut pas le trouver à l'instant.

26voto

oxbow_lakes Points 70013

<:< est pas un opérateur - c'est un identificateur et est donc l'un des:

  • le nom d'un type (classe, trait de caractère, de type alias etc)
  • le nom d'une méthode/val ou le var

Dans ce cas, <:< apparaît deux fois dans la bibliothèque, une fois dans Predef comme une classe et une fois en tant que méthode d' Manifest.

Pour la méthode sur Manifest, il vérifie si le type représenté par ce manifeste est un sous-type de celle représentée par le manifeste de l'argument.

Pour le type en Predef, ce qui est relativement nouveau, et je suis aussi un peu confus à ce sujet car il semble faire partie d'un triumvirat des déclarations identiques!

class <%<[-From, +To] extends (From) ⇒ To
class <:<[-From, +To] extends (From) ⇒ To
class =:=[From, To] extends (From) ⇒ To

14voto

aioobe Points 158466

J'ai demandé autour, et voici l'explication que j'ai eu:

<:< est généralement utilisé comme paramètre de preuve. Par exemple, en TraversableOnce , toMap est déclaré en tant que def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] . Ceci exprime la contrainte que la méthode toMap ne fonctionne que si le traversable contient 2-tuples. flatten est un autre exemple. <:< est utilisé pour exprimer la contrainte que vous ne pouvez aplatir qu'un traversable de traversables.

7voto

Daniel C. Sobral Points 159554

En fait, il vérifie si la classe représentée par le Manifest pomme est une sous-classe de la classe représentée par le fruit manifeste.

Par exemple:

 manifest[java.util.List[String]] <:< manifest[java.util.ArrayList[String]] == false
manifest[java.util.ArrayList[String]] <:< manifest[java.util.List[String]] == true
 

3voto

Eastsun Points 9053

Copier de scala.Predef.scala:

 // Type Constraints --------------------------------------------------------------

  // used, for example, in the encoding of generalized constraints
  // we need a new type constructor `<:<` and evidence `conforms`, as 
  // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred)
  // to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters)
  // simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`)
  // in part contributed by Jason Zaugg
  sealed abstract class <:<[-From, +To] extends (From => To)
  implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X