2012-06-13 19 views
7

Mam trochę kodu Scala, który wykorzystuje typy egzystencjalne, które uaktualniam do wersji 2.10, i zauważyłem ostrzeżenie o dodaniu "import language.existentials", co powoduje, że myślę, że powinien być lepszy sposób zapisu to. Kod mam sprowadza się do:Idiomatyczny zamiennik dla typów egzystencjalnych

class A { 
    private var values = Set.empty[(Class[_], String)] 
    def add(klass: Class[_], id: String) { 
    val key = (klass, id) 
    if (!values(key)) { 
     values += key 
     // More logic below.. 
    } 
    } 

uzyskać to ostrzeżenie:

[warn] test.scala:4 inferred existential type (Class[_$2], String) forSome { type _$2 }, which cannot be expressed by wildcards, should be enabled 
[warn] by making the implicit value language.existentials visible. 
[warn] This can be achieved by adding the import clause 'import language.existentials' 
[warn] or by setting the compiler option -language:existentials. 
[warn] See the Scala docs for value scala.language.existentials for a discussion 
[warn] why the feature should be explicitly enabled. 
[warn]  val key = (klass, id) 

czy istnieje sposób mogę przepisać mój kod nie generuje to ostrzeżenie (lub wymaga importu), czy też jest to najbardziej idiomatyczny sposób na wyrażenie tego? Nigdy nie pytam o parametr typu Class nigdzie w kodzie.

Odpowiedz

8

Ostrzeżenie dotyczy wnioskowania o typie egzystencjalnym, co zwykle jest niepożądane. Dodaj instrukcję importu lub wyraź ją:

val key: (Class[_], String) = (klass, id) 
+0

Przepraszam, nie rozumiem. Dlaczego wnioskowany typ jest niebezpieczny lub niepożądany? Parametr w klasie nie ma znaczenia, prawie nigdy nie ma miejsca, gdy masz do czynienia z zajęciami i refleksją (ponieważ jest on wymazywany, a zatem bezwartościowy w momencie, gdy jesteś zmuszony do sprawdzenia lub użycia informacji o klasie). Dlaczego mamy być zmuszeni do napisania zbędnej deklaracji typu dla czegoś tak jasnego i prostego, jak klucz w tym przypadku. Tam * znajduje się * deklaracja typu jedna linia powyżej, więc gdzie jest problem? – Ichthyo

+0

Pozwól mi wyjaśnić: Jestem świadomy, że możesz budować bardzo skomplikowane i mylące rzeczy z pełną składnią dla typów egzystencjalnych. Ale w tym przypadku tutaj, gdzie jest problem lub niebezpieczeństwo? 'Klasa [_]' wydaje się być wystarczająca dla – Ichthyo

+0

@Ichthyo, która może być prawdziwa dla klasy, ale lista egzystencjalna nie jest prawie tak użyteczna, na przykład. Parametr type na Class jest w większości bezużyteczny, dlatego egzystencja z nim nie jest wielka. –

4

Jeśli podasz parametr typu dla metody dodawania, ostrzeżenie zniknie. Nie ma to wpływu na to, co może być przechowywane w wartościach var. Nie mam dobrej odpowiedzi na pytanie, dlaczego, ale jest to obejście. Mam nadzieję, że ktoś bardziej zdolny odpowie również z wyjaśnieniem.

class A { 
    private var values = Set.empty[(Class[_], String)] 

    def add[T](klass: Class[T], id: String) { 
     val key = (klass, id) 
     if (!values(key)) { 
     values += key 
     // More logic below.. 
     } 
    } 
    }