2010-12-13 6 views
3
trait Link[This] { 
    var next:This = null 
} 

donne « incompatibilité de type Trouvée: null (null) requis: Ce »À quoi un type doit-il être contraint avant qu'il puisse être assigné "null"?

donc sans doute je dois dire que le type vérificateur Cela va être un type qui peut être attribué nulle. Comment puis-je faire cela?

(S'il y a un site que je devrais lire avant de poser des questions comme celle-ci, s'il vous plaît me montrer du doigt. Je suis actuellement à mi-chemin à travers la prépublication du 2e édition de la programmation Scala)

Répondre

8

Vous avez à contraindre This être une superclasse de Null - qui est la façon de dire au compilateur que null est une valeur valide pour ce type. (En fait, penser à Any, AnyRef et AnyVal seulement Muddles le problème - il suffit de demander au compilateur de ce que vous voulez!)

trait Link[This >: Null] { 
    var next:This = null 
} 

Cependant, je vous suggère d'éviter d'utiliser null, vous pouvez utiliser Option[This] et affecter None - une telle construction vous permettra d'utiliser la correspondance de modèle, et est une déclaration très forte que les clients utilisant ce champ devraient s'attendre à ce qu'il n'ait peut-être aucune valeur.

trait Link[This] { 
    var next:Option[This] = None 
} 
+0

Tout à fait raison à propos de l'option et il ira finalement comme ça. Mais c'est une étape dans la refactorisation du code originellement en Java, et il y a trop d'utilisations de null pour le faire maintenant –

0
trait Link { 
    var next:This = null 
} 

Cela devrait fonctionner. Y a-t-il une raison spécifique dont vous voulez avoir besoin pour paramétrer le trait avec un type?

+0

Y a-t-il une raison spécifique pour laquelle vous supposez que la classe 'Link' est seulement aussi complexe que l'extrait qu'il a écrit? –

+0

Oui, il y a une raison - ceci est mélangé dans une autre classe et je construis une liste chaînée de cette classe. –

0

Ma première pensée, qui n'a pas fonctionné. Je ne suis pas sûr pourquoi.

trait Link[This <: AnyRef] { // Without the type bound, it's Any 
    var next: This = null 
} 

Quand le pire arrive au pire des cas, il y a casting toujours:

trait Link[This <: AnyRef] { 
    var next: This = null.asInstanceOf[This] 
} 

Avec le casting, on n'a plus besoin du type lié à ce trait à la compilation, bien que vous voudrez peut-être là pour d'autres raisons .

+0

Je crois que la raison est que "extends' AnyRef' "et" accepte null "comme une valeur" sont logiquement distincts - on pourrait voir le fait que tous les types actuellement disponibles dans la JVM satisfont ou nient les deux comme un détail d'implémentation . –

+1

Cela n'a pas fonctionné car il y a l'idée que certaines classes de 'AnyRef' pourraient être forcées à ne pas être nulles. Vous avez donc besoin de 'trait Link [This>: Null <: AnyRef]'. Mais rien dans 'AnyVal' n'est une superclasse de' Null' de toute façon, donc 'Link [This>: Null]' est suffisant. –

Questions connexes