2013-03-09 11 views
13

Wenn eine Klasse eine convariant Typparameter wie Iterable[+A] hat, gibt es einen Unterschied zwischen erklärtVerständnis Scalas _ vs Any/Nothing

def foo(bar: Iterable[_]) 

und

def foo(bar: Iterable[Any]) 

?


Wenn eine Klasse eine kontraTypParameter wie Growable[-A] hat, gibt es einen Unterschied zwischen erklärt

def foo(bar: Growable[_]) 

und

def foo(bar: Growable[Nothing]) 

?

+2

möglich Duplikat von [Scala - Any vs Unterstrich in Generika] (http://stackoverflow.com/questions/15186520/scala-any-vs-underscore-in-generics) –

+0

Nicht ein genaues Duplikat, aber nahe genug. Ich lasse andere urteilen. –

Antwort

4

Es macht einen kleinen Unterschied, wenn der generische Parameter begrenzt ist. Zum Beispiel hatte, wenn Sie

class BoundedIterable[+A <: Something] 
class BoundedGrowable[-A >: Something] 

dann BoundedIterable[Any] geben und BoundedGrowable[Nothing] wäre illegal.

Ich weiß nicht, ob es einen anderen Unterschied gibt, aber ich kann mit Sicherheit sagen, dass Sie die Wildcard-lose Variante bevorzugen sollten, wo immer es möglich ist. Das liegt daran, dass der eigentliche Zweck der Deklaration-Site-Typ-Varianz darin besteht, Wildcards (die eine Form der Nutzung-Site-Varianz sind) loszuwerden. Wenn du List[Any] sagst, meinst du "Liste von allem", aber wenn du List[_] sagst, dann meinst du "Liste von wir-weiß-nicht-was". Das erstere ist also viel klarer, obwohl es in einem bestimmten Fall gleichwertig sein kann.

+0

Wenn ein Typparameter durch 'Something' begrenzt ist, könnten wir einfach' Something' anstelle von 'Any' /' Nothing' verwenden. In einem solchen Fall könnten wir 'def foo (bar: MyBoundedType [Something])' (sowohl für den kovarianten als auch den kontravarianten Fall) schreiben. –

+0

@Peter Das stimmt. Deshalb habe ich es "ein bisschen" anders genannt :) – ghik