6

Scala 2.11.2 następujące minimalne przykład sporządza jedynie przy użyciu rodzaju przypisanie na Array[String]:Scala rodzaju wnioskowanie: nie można wywnioskować IndexedSeq [t] z Array [T]

object Foo {  

    def fromList(list: List[String]): Foo = new Foo(list.toArray : Array[String]) 

} 

class Foo(source: IndexedSeq[String])  

Jeśli usunąć przypisanie typu w fromList, to nie skompilować z powodu następującego błędu:

Error:(48, 56) polymorphic expression cannot be instantiated to expected type; 
found : [B >: String]Array[B] 
required: IndexedSeq[String] 
    def fromList(list: List[String]): Foo = new Foo(list.toArray) 
                ^

Dlaczego nie kompilator wywnioskować Array[String] tutaj? Czy też ten problem musi coś zrobić z niejawną konwersją z Array do IndexedSeq?

+1

Uwaga myślę, że można zrobić: 'obiekt Foo {def z_listy (lista: Lista [String]): Foo = new Foo (list.toArray [String])} zamiast tego. – david

+0

Albo po prostu 'list.toIndexedSeq', oczywiście. Pytanie wciąż jest jednak dobre. –

+0

Dzięki za wskazanie tego. Powodem, dla którego wybieram 'Array's zamiast' IndexedSeq's jest wyłącznie ze względu na wydajność. Musiałem profilować tę funkcję i odkryłem, że 'Vector's bierze więcej na siebie przy tworzeniu wielu małych instancji. – Chris

Odpowiedz

4

Problem jest, że metoda .toArray zwraca tablicę pewnego rodzaju B który jest nadklasą T w List[T]. Pozwala to na użycie list.toArray na List[Bar], gdzie wymagany jest Array[Foo], jeśli Bar rozszerza się o Foo.

Tak, prawdziwy powód, dla którego to nie działa po wyjęciu z pudełka, polega na tym, że kompilator próbuje dowiedzieć się, którego z nich użyć, a także jak uzyskać. Wygląda na to, że próbuje rozwiązać wymaganie IndexedSeq[String], ale gwarantowane jest tylko lub nadklasa String; stąd błąd.

To jest mój preferowany obejść:

def fromList(list: List[String]): Foo = new Foo(list.toArray[String])