2014-11-03 10 views
6

Esiste un modo per ottenere l'errore di compilazione (o almeno un avviso) quando si assegnano alias di tipi diversi che condividono lo stesso tipo sottostante?Scala: impone l'errore di compilazione in caso di mancata corrispondenza dell'alias di tipo

In altre parole, dire che ho questo codice:

type Address = String 
type City = String 

def foo(x:Address) = ... 

voglio ottenere un errore di tempo di compilazione/avviso se faccio:

val city: City = "Dublin" 
foo(city) 

Per quanto posso dire, il il compilatore lo consente perché sono lo stesso tipo sottostante.

risposta

4

In base alle mie conoscenze, non è possibile ottenere questa "sicurezza del tipo" per la ricerca di alias di tipo. Tuttavia, esiste un'alternativa al tipo di alias che può essere utilizzato per ciò che desideri: Value Classes. Fondamentalmente, una classe di valore può darti un tipo senza allocare un nuovo oggetto. Tieni presente che esistono alcune limitazioni per le classi di valori che non hai per i tipi alias.

Per citare la documentazione Scala:

Correttezza

Un altro caso d'uso per classi di valore è quello di ottenere la sicurezza tipo di un tipo di dati senza il sovraccarico di assegnazione runtime. Ad esempio, un frammento di un tipo di dati che rappresenta una distanza potrebbe essere simile:

class Meter(val value: Double) extends AnyVal { 
    def +(m: Meter): Meter = new Meter(value + m.value) 
    } 

codice che aggiunge due distanze, come ad esempio

val x = new Meter(3.4) 
    val y = new Meter(4.3) 
    val z = x + y 

non sarà effettivamente allocare qualsiasi istanza di Meter, ma utilizzerà solo i doppi primitivi in ​​fase di runtime.

+0

Posso creare classi di casi di valore? Non mi piace l'utilizzo della nuova parola chiave –

+0

È possibile definire le classi caso valore. A proposito: il motivo per cui è possibile omettere la parola chiave 'new' è il metodo' apply' dell'oggetto (generato) companion-object, quindi non è necessario definire una classe case per sbarazzarsi della parola chiave. –

+0

Sì, lo so, preferisco semplicemente non definire i miei compagni per tutti i tipi di alias, è lungo e noioso^_ ^ –

3

No. Almeno, non senza modificare il compilatore (che potrebbe essere possibile con un plugin compilatore, o anche una macro), e se hai fatto questo cambiamento poi un sacco di biblioteche popolari (tra cui lo standard libreria) e gli esempi di codice standard non vengono compilati.

È possibile utilizzare le classi di valore, come descritto nella risposta di @Kulu. In alternativa, Scalaz Tagged Types evita il sovraccarico in più situazioni (ad esempio inserendole in una raccolta o utilizzando subst per aggiornare in modo sicuro un tipo generico che utilizza un tipo con tag).

Problemi correlati