2011-07-15 15 views
8

Mam problem ze zrozumieniem systemu granic typu scala. Co próbuję zrobić, to klasa, która posiada uchwyt elementy typu T, które można iteracyjne nad elementów typu A. To, co mam tak daleko jest:Ograniczenia parametrów typu Scala

class HasIterable[T <: Iterable[A], A](item:T){ 
    def printAll = for(i<-item) println(i.toString) 
} 

val hello = new HasIterable("hello") 

Klasa sama powodzeniem kompiluje ale próby utworzenia wartość hello daje mi ten błąd:

<console>:11: error: inferred type arguments [java.lang.String,Nothing] do 
not conform to class HasIterable's type parameter bounds [T <: Iterable[A],A] 
    val hello = new HasIterable("hello") 
      ^

Liczyłam hello rozwiązać jako HasIterable[String, Char] w tej sprawie. W jaki sposób rozwiązano ten problem?

Odpowiedz

17

String sam nie jest podtypem Iterable[Char], ale jego pimp, WrappedString, jest. W celu umożliwienia twoja definicja wykorzystać niejawne konwersje, trzeba użyć view bound (<%) zamiast upper type bound (<:):

class HasIterable[T <% Iterable[A], A](item:T){ 
    def printAll = for(i<-item) println(i.toString) 
} 

Teraz Twój przykład zadziała:

scala> val hello = new HasIterable("hello")    
hello: HasIterable[java.lang.String,Char] = [email protected] 
+1

będzie Czy możesz wyjaśnić, dlaczego to działa (a inne nie)? – dhg

+0

To zadziałało dla mnie, dzięki! I tak, dlaczego <% działa w tym przypadku? --aha Widzę twoją edycję. Dzięki :) – Dylan

+0

@pelotom: wielkie wyjaśnienie. dzięki! – dhg

Powiązane problemy