La tipizzazione di anatra sta decidendo il tipo di un oggetto, in base alle operazioni supportate e agli attributi che possiede. La tipizzazione strutturale è ... la stessa cosa?
Qual è esattamente la differenza?
La differenza principale è che la tipizzazione strutturale viene applicata durante l'analisi statica trovata in linguaggi tipizzati staticamente, mentre la digitazione anatra è un fenomeno di runtime che emerge dalla semantica degli oggetti dei linguaggi tipizzati dinamicamente.
Ad esempio, prendi il seguente codice Haxe (eseguibile qui ) usando la tipizzazione strutturale:
class Test {
static function main() {
var duck = {
quack: function () trace('Quack!!!'),
fly: function () trace('So let me take ... these broken wings ...')
};
duck.quack();
duck.fly();
duck.bark();
}
}
Quanto sopra non riuscirà a compilare dicendo
Test.hx:9: characters 8-17 : { quack : Void -> Void, fly : Void -> Void } has no field bark
Il compilatore rifiuta il codice, perché si accede a un campo non definito su un dato tipo strutturale. Il codice JavaScript equivalente genererebbe l'amata runtime eccezione
TypeError: undefined is not a function
Poiché la digitazione anatra avviene in fase di runtime, possiamo fare un'altra distinzione quando si tratta di programmi riflettenti. Si tratta più di chiedere "lo fa?" invece del normale "vero?" (con il cast solitamente conseguente). Quindi in pseudocode:
approccio "classico":
if (is(someObject, IDuck))
cast(someObject, IDuck).quack()
digitazione anatra:
if (hasMethod(someObject, 'quack'))
someObject.quack();
La tipizzazione di anatra dipende dagli oggetti che rispondono alle operazioni (ovvero messaggi o invocazioni di metodi) in un modo appropriato per loro. "Se cova come un'anatra, è abbastanza anatra da chiedergli di fare cose da anatra".
Ad esempio, in Python un oggetto dict
ha un metodo update
. Posso codificare altri tipi di oggetti che hanno anche un metodo update
:
class Able(object):
def update(self, data):
self.data = data
class Count(object):
def update(self, increment):
self.count += increment
self.times_updated += 1
Ora dict
, Able
e Count
istanze rispondono a update
, ma lo fanno in modi appropriati per loro stessi.
Alcune lingue (ad esempio Python, Ruby) sono molto amichevoli alla digitazione anatra, mentre altre (ad esempio Java) non lo sono. @ back2dos ha fornito un eccellente esempio di tipizzazione strutturale, i modi in cui il compilatore contrassegna le chiamate che non sono definite esplicitamente e il requisito comune per il casting di tipo esplicito nei linguaggi anonimo-ostili. I linguaggi di anatra come Python controllano la disponibilità del metodo in fase di esecuzione (in modo dinamico) anziché in fase di compilazione. Più importante, dal punto di vista dell'usabilità, è che non richiedono il cast di tipi per utilizzare metodi specifici. Qualsiasi metodo (o proprietà) può essere richiesto a qualsiasi oggetto in qualsiasi momento. Più che solo "zucchero sintattico", questa permissività è ciò che rende la digitazione anatra facile e utile.
Punto finale: la digitazione anatra non è solo una funzione linguistica, è anche un idioma e uno stile di utilizzo, una caratteristica della comunità del linguaggio di programmazione e dell'etica, non solo le specifiche del linguaggio e il compilatore.
Leggi altre domande sui tag type-systems duck-typing