Domanda

In Scala varianza può essere definito con gli operatori di varianza come + e - sul argomento di tipo generico. Ad esempio, il tipo List è covariante nella libreria standard.

class List[+A]

Quindi, una funzione con una lista covariant può essere definita in questo modo:

def foo[A](list : List[A])

Anche varianza può essere emulato con limiti generici. Così possiamo anche scrivere questo

def foo[A](list : List[_:< A])

Naturalmente questo non ha senso, perché è già list covariante. Ma lo stesso trucco potrebbe essere fatto per i tipi che non sono covariante. (Come Stack). Naturalmente, anche un nuovo tipo potrebbero essere creati dalla pila (eredità di aggregazione), che è covariante.

Così le mie domande:

  1. Quando devono poter utilizzare limiti generici per varianza? E quando dovremmo creare un nuovo tipo covariante?
  2. sono limiti generici utile solo per la varianza, o possono dichiarare di più (concetti linguistici).
  3. Se sono utili solo per la varianza, sono i limiti allora solo per la compatibilità con Java?

thx in anticipo:)

È stato utile?

Soluzione

Se un tipo è naturalmente covariante o controvarianti si dovrebbe dichiarare così. Gli utenti vi ringrazieranno per questo. La varianza utilizzo in loco è infatti in gran parte a causa della Java. Più precisamente, un tipo come Array[T <: Number] viene trattato come abbreviazione di tipo esistenziale:

ArrayBuffer[T] forSome { type T <: Number }

tipi esistenziali hanno una sintassi piuttosto ingombrante in Scala. Questo è una sorta di intenzionale, perché non è consigliabile li si usa molto. Quando si avrebbe bisogno di un tipo esistenziale?

  1. Per scrivere l'analogo di un tipo Java con caratteri jolly, come List<? extends Number>.
  2. Per scrivere l'analogo di tipo grezzo Java, come List.

In Java, i tipi prime e tipi jolly non sono proprio la stessa cosa e non è proprio la stessa cosa come un tipo esistenziale (anche se sappiamo ciò che non sono, è piuttosto difficile stabilire con precisione quello che sono). Ma sono abbastanza vicino a esistenziali, in pratica, in modo che alla Scala si allontana con loro mappatura a questo tipo di tipo.

Altri suggerimenti

  1. Quando si crea un nuovo tipo generico, dire Foo [T], si dovrebbe cercare è difficile stabilire se tale tipo è covariante, controvariante o invariante e dichiararla Foo [+ T], Foo [-T] o Foo [T] rispettivamente. Certo questo può essere un po 'difficile. Tuttavia, si libera l'utente di Foo di prendere questa decisione ogni volta che ha bisogno di usare un Foo utilizzando limiti generici. In breve: preferire dichiarazione sito varianza su chiamata sito varianza quando la varianza è una proprietà di tipo in sé.

A proposito, la programmazione a Scala libro di Martin Odersky, Lex Spoon e Bill Venners ha alcune grandi seactions circa varianza. Vedere il Capitolo 19 Tipo parametrizzazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top