2010-12-01 2 views
3

Ce que je veux dire est ceci:Pourquoi les limites des paramètres de type sont-elles ignorées lors de l'utilisation de types existentiels dans Scala?

scala> class Bounded[T <: String](val t: T) 
defined class Bounded 

scala> val b: Bounded[_] = new Bounded("some string") 
b: Bounded[_] = [email protected] 

scala> b.t 
res0: Any = some string 

Pourquoi res0 sont de type ANY et non chaîne? Il pourrait bien savoir que b.t est au moins une chaîne. L'écriture

val b: Bounded[_ <: String] = new Bounded("some string") 

fonctionne, mais elle est redondante par rapport à la déclaration de la classe elle-même.

+0

Pourquoi pas simplement 'val b = new Bounded (" une chaîne de caractères ")'? b est déduit comme Bounded [String]. – IttayD

+0

N'est-ce pas exactement comme demander pourquoi 'val o: Any =" une chaîne "' a le type de Any au lieu de String? – IttayD

+0

@IttayD Oui, vous pouvez omettre l'annotation de type. Mon problème réel était dans un argument de méthode, où vous ne pouvez pas l'omettre. En outre, je ne suis pas d'accord avec votre deuxième commentaire: quand j'écris 'b.t', je récupère un objet de type T <: String, donc au moins un String, comme le garantit la définition de Bounded. Par conséquent, j'espérais que res0 aurait du type String et pas n'importe lequel, sans utiliser une annotation de type comme dans votre exemple. –

Répondre

5

D'abord, j'ai édité le titre de la question. Vous n'utilisez pas les types dépendants, que Scala n'a pas de toute façon, mais types existentiels. Deuxièmement, vous ne déduisez rien, vous déclarez explicitement le type. Maintenant, si vous avez écrit Bounded[Any], Scala ne vous le permettrait pas. Cependant, l'une des utilisations des types existentiels est de traiter des situations où le paramètre de type est complètement inconnu - comme les types bruts de Java, où. Donc je suppose que faire une exception dans une situation qui semble assez évidente va casser une autre situation où le type existentiel est la seule façon de faire face à quelque chose.

+0

Merci pour les modifications, Daniel. Maintenant, je n'insiste pas sur l'utilisation de "types existentiels", je voudrais juste accéder à b.t passé d'un objet Bounded avec une paramétrisation inconnue, et savoir que c'est une chaîne et pas n'importe. Est-ce la seule solution pour écrire le type lié comme dans 'val b: Bounded [_

+0

@JPP Si vous voulez savoir comment éviter d'écrire les limites partout, posez-le sur une autre question. Personne ne cliquerait sur la question _this_ pour chercher cette réponse! :-) –

2

Il y a eu une longue discussion sur ce sujet récemment sur la liste de diffusion, Type Boundary "Stickyness" on Wildcards.

Il n'était pas concluant, sauf pour convenir que les types existentiels, tels que Bounded[_] (un raccourci pour Bounded[$1] forSome { type $1 }), ne se prêtent pas à l'intuition.

@extempore a trouvé un côté positif à la discussion :)

Du côté plus je suis enfin lire la couverture de spécification pour couvrir. Je n'avais aucune idée les paroles complètes pour "jaune sous-marin" étaient dans la spécification! Pourtant, je dois admettre, dans le contexte c'était difficile de voir d'une autre manière que la section aurait pu être écrite.

+0

"Je n'avais aucune idée que les paroles complètes de" sous-marin jaune "étaient dans la spécification!" ... Où? Quelles pages? :-P – soc

Questions connexes