2013-03-09 36 views
13

Jeśli klasa ma convariant parametr typu takiego jak Iterable[+A], jest jakaś różnica między deklarowaniaZrozumienie Scala _ vs Wszelkie/Nothing

def foo(bar: Iterable[_]) 

i

def foo(bar: Iterable[Any]) 

?


Jeśli klasa ma kontrawariantny parametr typu takiego jak Growable[-A], jest jakaś różnica między deklarowania

def foo(bar: Growable[_]) 

i

def foo(bar: Growable[Nothing]) 

?

+2

możliwy duplikat [scala - Any vs podkreślnik w generycznych] (http://stackoverflow.com/questions/15186520/scala-any-vs-underscore-in-generics) –

+0

Nie dokładny duplikat, ale wystarczająco blisko. Pozwolę innym sądzić. –

Odpowiedz

4

To ma niewielką różnicę, gdy ogólny parametr jest ograniczony. Na przykład, jeśli miał

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

następnie wpisz BoundedIterable[Any] i BoundedGrowable[Nothing] byłoby nielegalne.

Nie wiem, czy jest jakakolwiek inna różnica, ale mogę powiedzieć na pewno, że w miarę możliwości powinieneś preferować wariant bez symboli wieloznacznych. Dzieje się tak, ponieważ w rzeczywistości celem wariancji typu deklaracji-miejsca jest pozbycie się symboli wieloznacznych (które są odmianą wariancji strony użytkowej). Kiedy mówisz List[Any] masz na myśli "listę czegokolwiek", ale kiedy mówisz List[_], masz na myśli "listę nie-nie-wiem-co". Więc ta pierwsza jest po prostu bardziej przejrzysta, nawet jeśli mogą być one równoważne w konkretnym przypadku.

+0

Jeśli parametr typu jest ograniczony przez 'Something', możemy po prostu użyć' Something' w miejsce 'Any' /' Nothing'. W takim przypadku możemy napisać 'def foo (bar: MyBoundedType [Something])' (zarówno w przypadku kowariancji, jak i contravariant). –

+0

@Peter To prawda. Dlatego nazwałem to "małą" różnicą :) – ghik