Qual è la differenza tra linguaggi staticamente tipizzati e dinamicamente tipizzati?
-
19-09-2019 - |
Domanda
Ho sentito un sacco che i nuovi linguaggi di programmazione vengono digitati in modo dinamico, ma che cosa significa veramente quando diciamo che una lingua è dinamicamente tipizzato vs tipizzazione statica?
Soluzione
lingue staticamente tipizzati
Una lingua è staticamente tipizzato se il tipo di una variabile è noto al momento della compilazione. Per alcune lingue questo significa che voi come il programmatore necessario specificare quale tipo ogni variabile è (es .: Java, C, C ++); altre lingue offrono una qualche forma di inferenza di tipo , la capacità del sistema di tipo di dedurre il tipo di una variabile (ad es .: OCaml, Haskell, Scala, Kotlin)
Il vantaggio principale è che tutti i tipi di controllo può essere fatto dal compilatore, e quindi un sacco di bug banali sono catturati in una fase molto precoce.
Esempi: C, C ++, Java, Rust, Go, Scala
lingue dinamicamente tipizzati
Una lingua viene digitato in modo dinamico se il tipo è associata a valori di run-time, e non nominato variabili / campi / etc. Ciò significa che il programmatore può scrivere un po 'più veloce perché non c'è bisogno di specificare i tipi ogni volta (a meno di utilizzare un linguaggio staticamente tipizzato con inferenza di tipo ).
Esempi: Perl, Ruby, Python, PHP, JavaScript
La maggior parte dei linguaggi di scripting hanno questa caratteristica in quanto non v'è alcun compilatore di fare tipo-controllo in ogni modo statico, ma si può trovare se stessi alla ricerca di un bug che è dovuto l'interprete mal interpretare il tipo di una variabile. Per fortuna, gli script tendono ad essere piccoli così gli insetti non hanno così tanti posti in cui nascondersi.
La maggior parte lingue dinamicamente tipizzati fanno consentono di fornire informazioni sul tipo, ma non lo richiedono. Una lingua che è attualmente in fase di sviluppo, Rascal , adotta un approccio ibrido che consente la tipizzazione dinamica all'interno di funzioni, ma far rispettare statica digitando per la firma della funzione.
Altri suggerimenti
linguaggi di programmazione staticamente tipizzati non tipo di controllo (vale a dire il processo di verifica e di far rispettare i vincoli di tipi) a a tempo di compilazione a differenza di run-time .
linguaggi di programmazione dinamicamente tipizzati non digitare il controllo a run-time invece di a tempo di compilazione .
Ecco un esempio di contrasto come Python (tipizzato in modo dinamico) e Go (staticamente tipizzato) gestiscono un errore di tipo:
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
Python non digitare il controllo in fase di esecuzione, e quindi:
silly(2)
funziona perfettamente bene, e produce il Hi
output previsto. Errore viene generato solo se la linea problematica è colpito:
silly(-1)
Produce
TypeError: unsupported operand type(s) for +: 'int' and 'str'
perché la linea pertinenti sono state effettivamente eseguita.
Vai d'altra parte non tipo-controllo in fase di compilazione:
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
È possibile che questo non verrà compilato, con il seguente errore:
invalid operation: "3" + 5 (mismatched types string and int)
In poche parole in questo modo: in un linguaggio a tipizzazione statica tipi variabili sono static , che significa una volta impostato una variabile a un tipo, non è possibile cambiarlo. Questo perché battitura è associata alla variabile anziché il valore si riferisce.
Ad esempio in Java:
String str = "Hello"; //variable str statically typed as string
str = 5; //would throw an error since str is supposed to be a string only
Quando al contrario: in un linguaggio tipizzato dinamicamente tipi variabili sono dinamica , che significa dopo aver impostato una variabile a un tipo, si può cambiare. Questo perché battitura è associato con il valore assume invece che la variabile stessa.
Ad esempio in Python:
str = "Hello" # variable str is linked to a string value
str = 5 # now it is linked to an integer value; perfectly OK
Quindi, è meglio pensare di variabili nei linguaggi dinamicamente tipizzati come solo puntatori generici ai valori digitati.
In sintesi, Tipo descrive (o avrebbe dovuto descritta) le variabili nella lingua piuttosto che il linguaggio stesso. Avrebbe potuto essere meglio utilizzati come una lingua con staticamente tipizzato le variabili contro una lingua con dinamicamente tipizzato le variabili IMHO.
lingue staticamente tipizzati sono lingue generalmente compilati, in tal modo, i compilatori controllare i tipi (hanno perfettamente senso giusto? Come tipi non sono autorizzati a essere cambiato in seguito in fase di esecuzione).
lingue dinamicamente tipizzati vengono interpretati, quindi digitare controllo (se presente) avviene in fase di esecuzione quando vengono utilizzati. Questo naturalmente porta con sé alcune costo delle prestazioni, ed è uno dei motivi per linguaggi dinamici (per esempio, Python, Ruby, PHP) non scalano buoni come quelli digitati (Java, C #, ecc). Da un'altra prospettiva, staticamente tipizzati lingue hanno più di un costo di start-up: ti fa di solito scrive più codice, codice più difficile. Ma che paga successivamente spento.
La cosa buona è entrambe le parti sono prestiti caratteristiche dall'altro lato. linguaggi tipizzati stanno incorporando caratteristiche più dinamiche, ad esempio, generici e librerie dinamiche in c # e linguaggi dinamici sono inclusivi più verifica del tipo, ad esempio, le annotazioni di tipo in pitone, o hack variante di PHP, che di solito non sono fondamentali per la lingua e utilizzabile su richiesta.
Quando si tratta di scelta della tecnologia, nessuna delle due parti ha una intrinseca superiorità sugli altri. E 'solo una questione di preferenza se si desidera un maggiore controllo per cominciare o la flessibilità. basta scegliere lo strumento giusto per il lavoro, e assicuratevi di controllare ciò che è disponibile in termini di opposta prima di considerare un interruttore.
http://en.wikipedia.org/wiki/Type_system
tipizzazione statica
Un linguaggio di programmazione è detto di usare tipizzazione statica quando il tipo di controllo è eseguita durante tempo di compilazione come al contrario di run-time. In tipizzazione statica, tipi sono associati con variabili non i valori. lingue tipi statici includere Ada, C, C ++, C #, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (Rispetto a distinguere scalari, array, hash e subroutine) e Scala. tipizzazione statica è una forma limitata di programma verifica (vedi sicurezza tipo): di conseguenza, permette molti tipo errori di essere catturati nelle prime fasi del ciclo di sviluppo. tipo statico pedine valutano solo il tipo informazioni che possono essere determinata a tempo di compilazione, ma sono in grado di verificare che le condizioni controllato valgono per tutte le possibili esecuzioni del programma, che elimina la necessità di tipo di ripetizione verifica ogni volta che il programma viene eseguito. L'esecuzione del programma può anche essere resa più efficiente (cioè più veloce o prendendo di memoria ridotto) per omettendo controlli di tipo runtime e consentendo altre ottimizzazioni.
A causa valutano le informazioni sul tipo durante la compilazione, e quindi la mancanza digitare le informazioni che è solo disponibile in fase di esecuzione, di tipo statico pedine sono conservatori. saranno rifiutare alcuni programmi che possono essere ben educati a run-time, ma che non può essere determinato staticamente essere ben tipato. Ad esempio, anche se un espressione sempre viene valutata a true a run-time, un programma che contiene il codice
if <complex test> then 42 else <type error>
saranno respinte come mal digitato, perché un'analisi statica non può determinare che il ramo altrimenti non sarà preso. [1] Il comportamento conservatore di pedine tipo statico è vantaggiosa quando è falsa rado: A Tipo checker statico può rilevare tipo errori nei percorsi di codice usato raramente. Senza controllo di tipo statico, anche test di copertura del codice con il codice 100% copertura può essere in grado di trovare tale digitare errori. test di copertura codice può non rilevare tali errori di tipo perché la combinazione di tutti i luoghi dove vengono creati i valori e tutti luoghi in cui viene utilizzato un determinato valore devono essere presi in considerazione.
Il più utilizzato staticamente tipizzato le lingue non sono di tipo formale al sicuro. Hanno "scappatoie" nel specifica del linguaggio di programmazione consentendo ai programmatori di scrivere codice che aggira la verifica eseguita da un tipo di controllo statico e in modo da affrontare una vasta gamma di problemi. Ad esempio, Java e la maggior parte in stile C lingue hanno tipo giochi di parole, e Haskell ha tali caratteristiche come unsafePerformIO: tali operazioni possono essere pericoloso in fase di esecuzione, in quanto possono causare un comportamento indesiderato a causa di tipizzazione errata di valori quando la programma viene eseguito.
tipizzazione dinamica
Un linguaggio di programmazione è detto di essere dinamicamente tipizzati, o semplicemente 'dinamica', quando la maggior parte del suo controllo dei tipi viene eseguita in fase di esecuzione anziché a tempo di compilazione. In tipizzazione dinamica, tipi sono associati a valori non variabili. lingue dinamicamente tipizzati includere Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (rispetto al tipi definiti dall'utente, ma non built-in tipi), PHP, Prolog, Python, Ruby, Smalltalk e Tcl. Rispetto alla statica tipizzazione, la tipizzazione dinamica può essere più flessibile (per esempio consentendo programmi ai generare tipi e funzionalità basate sui dati di run-time), anche se al scapito di un minor numero di una garanzia a priori. Questo perché un tipizzato dinamicamente lingua accetta e cerca di eseguire alcuni programmi che possono essere governato come non validi da un tipo statico checker.
tipizzazione dinamica può provocare runtime digitare errori, cioè in fase di esecuzione, un valore può avere un tipo di inaspettato, unND un'operazione senza senso per quel tipo viene applicata. si può verificare questa operazione molto tempo dopo il luogo dove il errore di programmazione è stato fatto, cioè, il luogo in cui il tipo sbagliato di dati passato in un luogo non dovrebbe avere. Questo rende il bug difficile da individuare.
sistemi linguistici dinamicamente tipizzati, rispetto al loro tipizzazione statica cugini, rendono meno "a tempo di compilazione" controlli sul codice sorgente (ma sarà verificare, ad esempio, che il programma è sintatticamente corretto). Run-time controlli possono potenzialmente essere più sofisticato, dal momento che possono usare informazioni dinamiche come pure qualsiasi informazioni che era presente durante compilazione. D'altro canto, controlli runtime solo affermano che condizioni tengono in particolare esecuzione del programma, e queste controlli vengono ripetuti per ogni esecuzione del programma.
Sviluppo in tipizzato dinamicamente lingue è spesso supportati da pratiche di programmazione come unità test. Il test è una pratica fondamentale per lo sviluppo di software professionale, e è particolarmente importante dinamicamente tipizzati lingue. Nel pratica, il test fatto per garantire funzionamento programma corretto grado di rilevare una molto più ampia gamma di errori che statico tipo-controllo, ma al contrario non può cercare nel modo più completo per la errori che sia test e statico verifica del tipo in grado di rilevare. Il test può essere incorporato nel ciclo di build del software, nel qual caso può essere pensato come un "tempo di compilazione" check-in l'utente il programma non è necessario eseguire manualmente tali prove.
Riferimenti
- Pierce, Benjamin (2002). Tipi e linguaggi di programmazione. MIT Press. ISBN 0-262-16209-1.
La terminologia "digitato in modo dinamico" è purtroppo fuorviante. Tutte le lingue sono staticamente tipizzati, e tipi sono proprietà delle espressioni (non su valori come alcuni pensano). Tuttavia, alcune lingue hanno un solo tipo. Questi sono chiamati lingue uni-digitato. Un esempio di un tale linguaggio è il lambda calcolo tipizzato.
Nel lambda calcolo tipizzato, tutti i termini sono termini lambda, e l'unica operazione che può essere eseguita su un termine è applicare ad un altro termine. Quindi tutte le operazioni risultano sempre in entrambi ricorsione infinito o un termine lambda, ma mai segnalazione di eventuali errori.
Tuttavia, se dovessimo aumentare il lambda calcolo tipizzato con i numeri primitive e le operazioni aritmetiche, allora potremmo eseguire operazioni senza senso, come l'aggiunta di due termini lambda insieme: (λx.x) + (λy.y)
. Si potrebbe sostenere che l'unica cosa sana da fare è segnalare un errore quando questo accade, ma per poter fare questo, ogni valore deve essere etichettato con un indicatore che indica se il termine è un termine lambda o un numero. Inoltre l'operatore controllerà che infatti entrambi gli argomenti sono contrassegnati come numeri, e se non lo sono, segnalare un errore. Si noti che questi tag sono non tipo, perché i tipi sono proprietà dei programmi, non di valori prodotti da tali programmi.
Un linguaggio uni tipizzato che fa questo si chiama digitato in modo dinamico.
Lingue come JavaScript, Python e Ruby sono tutti uni-digitato. Anche in questo caso, l'operatore typeof
in JavaScript e la funzione type
in Python hanno nomi fuorvianti; tornano i tag associati ai operandi, non i loro tipi. Allo stesso modo, dynamic_cast
in C ++ e instanceof
in Java fare non fare controlli di tipo.
vs. Compilato interpretati
"Quando il codice sorgente è tradotto"
- Codice Sorgente : Codice originale (di solito digitato da un essere umano in un computer)
- Traduzione : La conversione di codice sorgente in qualcosa di un computer in grado di leggere (cioè codice macchina)
- Run-Time : Periodo quando il programma è in esecuzione comandi (dopo la compilazione, se compilato)
- linguaggio compilato : Codice tradotto prima del run-time
- Interpretata lingua : Codice tradotto al volo, durante l'esecuzione
Digitando
"Quando tipi vengono controllati"
5 + '3'
è un esempio di un errore di tipo in fortemente tipizzato linguaggi come Python e Go, perché non permettono di "tipo la coercizione" -> la possibilità per un valore di cambiare il tipo di determinati contesti quali la fusione di due tipi. debolmente tipizzato lingue, come JavaScript, non gettare un errore di tipo (risultati in '53'
).
- Static : Tipi controllati prima di run-time
- dinamica : Tipi controllato al volo, durante l'esecuzione
Le definizioni di "Static & Compilato" e "Dynamic & interpretato" sono abbastanza simili ... ma ricorda che è "quando tipi vengono controllati" vs "quando il codice sorgente è tradotto".
Otterrete gli stessi errori di tipo indipendentemente dal fatto che la lingua è compilato o interpretato ! È necessario separare questi termini concettualmente.
Python Esempio
dinamico, interpretato
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
silly(2)
A causa Python è sia interpretata e dinamico digitato, si traduce solo e tipo-codice controlla è in esecuzione su. Il blocco else
mai eseguito, in modo 5 + '3'
è mai nemmeno guardato!
Che cosa succede se si è staticamente tipizzato?
Un errore di tipo sarebbe stato gettato prima che il codice è ancora eseguito. Si esibisce ancora digitare-controllo prima di run-time, anche se viene interpretato.
Che cosa succede se è stato compilato?
Il blocco else
sarebbe tradotto / guardato prima di run-time, ma perché è dinamicamente tipizzato non avrebbe generato un errore! Dinamicamente tipizzati lingue non controllano i tipi fino all'esecuzione, e che la linea non esegue.
Vai Esempio
Static, compilato
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
I tipi vengono controllati prima di avviare (statico) e il tipo di errore viene immediatamente catturato! I tipi sarebbero comunque controllati prima fase di esecuzione se è stato interpretato, con lo stesso risultato. Se fosse dinamica, non sarebbe gettare eventuali errori anche se il codice sarebbe essere considerato svincolato durante la compilazione.
Prestazioni
Un linguaggio compilato avrà prestazioni migliori in fase di esecuzione se è staticamente tipizzato (vs. dinamicamente); la conoscenza dei tipi consente di ottimizzare il codice macchina.
lingue staticamente tipizzati avere prestazioni migliori in fase di esecuzione intrinsecamente a causa di non aver bisogno di controllare i tipi di dinamicamente durante l'esecuzione (controlla prima esecuzione).
Allo stesso modo, linguaggi compilati sono più veloci in fase di esecuzione del codice è già stato tradotto invece di aver bisogno di "interpretare" / tradurlo al volo.
Si noti che sia compilato e staticamente tipizzati lingue avranno un ritardo prima di eseguire per la traduzione e il tipo di controllo, rispettivamente.
più differenze
tipizzazione statica cattura errori all'inizio, invece di trovare loro durante l'esecuzione (particolarmente utile per i programmi lunghi). E 'più "rigorosa", in quanto non permetterà per gli errori di tipo ovunque nel programma e spesso impedisce variabili da tipi di cambiamento, che difende ulteriormente contro gli errori non intenzionali.
num = 2
num = '3' // ERROR
tipizzazione dinamica è più flessibile, che alcuni apprezzano. Esso consente in genere per le variabili di modificare i tipi, che può risultare in errori imprevisti.
lingue staticamente tipizzati tipo di controllo in fase di compilazione e il tipo non può cambiare. (Non ottenere carino con commenti del tipo di fusione, viene creata una nuova variabile / di riferimento).
dinamicamente tipizzati lingue tipo di controllo in fase di esecuzione e il tipo di una variabile può essere modificata in fase di esecuzione.
lingue staticamente tipizzati : ogni variabile e l'espressione è già noto al momento della compilazione.
(int a;
a può assumere solo valori di tipo integer durante l'esecuzione)
Esempi: C, C ++, Java
lingue dinamicamente tipizzati : le variabili possono ricevere valori diversi in fase di esecuzione e il loro tipo è definito in fase di esecuzione.
(var a;
una può prendere qualsiasi tipo di valori in fase di esecuzione)
Esempi:. Ruby, Python
Dolce e definizioni, ma il montaggio della necessità: lingue tipi statici lega il tipo di una variabile per tutta la sua portata (Seg: Scala) lingue dinamicamente tipizzati legano il tipo che il valore effettivo a cui fa riferimento una variabile.
- In un linguaggio tipizzato staticamente, una variabile è associato a un tipo che è noto al momento della compilazione, e che tipo rimane invariato durante l'esecuzione di un programma. Equivalentemente, la variabile può essere assegnato solo un valore che è un esempio del tipo noto / specificato.
- In un linguaggio tipizzato in modo dinamico, una variabile non ha alcun tipo, ed il suo valore durante l'esecuzione può essere qualsiasi cosa, di qualsiasi forma e la forma.
lingue staticamente tipizzati come C ++, Java e dinamicamente tipizzati linguaggi come Python differiscono solo in termini di esecuzione del tipo della variabile. staticamente tipizzati le lingue hanno tipo di dati statici per la variabile, ecco il tipo di dati viene controllato durante la compilazione in modo debug è molto più semplice ... mentre dinamicamente tipizzato lingue non fanno il stesso, il tipo di dati viene controllato che esegue il programma e quindi il debugging è po 'difficile.
Inoltre hanno una differenza molto piccola e può essere correlato con fortemente tipizzati e debolmente tipizzato Lingue. Un linguaggio fortemente tipizzato non consente l'utilizzo di un tipo come un altro esempio. C e C ++ ... mentre le lingue debolmente tipizzato permettono eg.python
linguaggio tipizzato dinamicamente consente di prototipare rapidamente i concetti di algoritmo senza il sovraccarico di circa pensare quali tipi di variabili devono essere utilizzati (che è una necessità in staticamente tipizzato languag e) .
Static digitato lingue (compilatore per la risoluzione chiamate di metodo e compilare i riferimenti):
- di solito una migliore performance
- compilazione più veloce di feedback errore
- un migliore supporto IDE
- Non adatto per l'utilizzo di formati di dati non definito
- di più per avviare uno sviluppo in cui il modello non è definito quando
- il tempo di compilazione più lungo
- in molti casi richiede di scrivere più codice
dinamico digitato lingue (decisioni prese in programma in esecuzione):
- prestazioni inferiori
- un più rapido sviluppo
- alcuni bug potrebbero essere rilevati solo successivamente in fase di esecuzione
- buono per i formati di dati non definiti (meta di programmazione)
tipizzazione statica: I linguaggi come Java e Scala sono digitato statici.
Le variabili devono essere definite e inizializzato prima di essere utilizzati in un codice.
per es. int x; x = 10;
System.out.println (x);
Dinamico Digitando: Perl è un linguaggio tipizzato dinamica.
variabili non devono essere inizializzati prima di essere utilizzati nel codice.
y = 10; utilizzare questa variabile nella parte successiva di codice