Programmazione Dart - Guida rapida

Dart è un linguaggio orientato agli oggetti con sintassi in stile C che può opzionalmente essere compilato in JavaScript. Supporta una vasta gamma di aiuti alla programmazione come interfacce, classi, raccolte, generici e digitazione opzionale.

Dart può essere ampiamente utilizzato per creare applicazioni a pagina singola. Le applicazioni a pagina singola si applicano solo a siti Web e applicazioni Web. Le applicazioni a pagina singola consentono la navigazione tra le diverse schermate del sito Web senza caricare una pagina Web diversa nel browser. Un classico esempio èGMail ─ quando fai clic su un messaggio nella tua posta in arrivo, il browser rimane sulla stessa pagina web, ma il codice JavaScript nasconde la posta in arrivo e porta il corpo del messaggio sullo schermo.

Google ha rilasciato una build speciale di Chromium - il Dart VM. L'uso di Dartium significa che non devi compilare il tuo codice in JavaScript finché non sei pronto per il test su altri browser.

La tabella seguente confronta le funzionalità di Dart e JavaScript.

Caratteristica Dardo JavaScript
Tipo di sistema Opzionale, dinamico Debole, dinamico
Classi Sì, unica eredità Prototipico
Interfacce Sì, più interfacce No
Concorrenza Sì, con isolati Sì, con i web worker HTML5

Questo tutorial fornisce una conoscenza di livello base del linguaggio di programmazione Dart.

In questo capitolo viene illustrata la configurazione dell'ambiente di esecuzione per Dart sulla piattaforma Windows.

Esecuzione di script online con DartPad

Puoi testare i tuoi script online utilizzando l'editor online all'indirizzo https://dartpad.dartlang.org/. L'Editor Dart esegue lo script e visualizza sia l'HTML che l'output della console. L'editor in linea viene fornito con una serie di esempi di codice preimpostati.

Uno screenshot del file Dartpad l'editor è riportato di seguito -

Dartpad consente anche di codificare in modo più restrittivo. Ciò può essere ottenuto selezionando l'opzione Modalità forte in basso a destra nell'editor. La modalità forte aiuta con -

  • Controllo statico e dinamico più forte
  • Generazione di codice JavaScript idiomatico per una migliore interoperabilità.

Puoi provare il seguente esempio usando Dartpad

void main() { 
   print('hello world'); 
}

Il codice visualizzerà il seguente output

hello world

Configurazione dell'ambiente locale

In questa sezione, vediamo come impostare l'ambiente locale.

Utilizzando l'editor di testo

Esempi di alcuni editor includono Blocco note di Windows, Blocco note ++, Emacs, vim o vi, ecc. Gli editor possono variare da un sistema operativo all'altro. I file di origine sono in genere denominati con l'estensione ".dart".

Installazione di Dart SDK

L'attuale versione stabile di Dart è 1.21.0. Ildart sdk può essere scaricato da -

  • https://www.dartlang.org/install/archive

  • http://www.gekorm.com/dart-windows/

Di seguito è riportato uno screenshot dell'installazione di Dart SDK:

Al termine dell'installazione dell'SDK, impostare la variabile d'ambiente PATH su -

<dart-sdk-path>\bin

Verifica dell'installazione

Per verificare se Dart è stato installato correttamente, apri il prompt dei comandi e inserisci il seguente comando:

Dart

Se l'installazione ha esito positivo, mostrerà il runtime di dart.

Supporto IDE

Una pletora di IDE supporta lo scripting in Dart. Esempi inclusiEclipse, IntelliJ, e WebStorm da Jet Brains.

Di seguito sono riportati i passaggi per configurare l'ambiente Dart utilizzando WebStrom IDE.

Installazione di WebStorm

Il file di installazione per WebStorm può essere scaricato da https://www.jetbrains.com/webstorm/download/#section=windows-version.

Il file di installazione di WebStorm è disponibile per Mac OS, Windows e Linux.

Dopo aver scaricato i file di installazione, seguire i passaggi indicati di seguito:

  • Installa Dart SDK: fai riferimento ai passaggi sopra elencati

  • Crea un nuovo progetto Dart e configura il supporto Dart

  • Per creare un nuovo progetto Dart,

    • Clic Create New Project dalla schermata di benvenuto

    • Nella finestra di dialogo successiva, fare clic su Dart

  • Se non è specificato alcun valore per Dart SDKpath, quindi fornisci il percorso SDK. Ad esempio, il percorso dell'SDK potrebbe essere<dart installation directory>/dart/dartsdk.

Aggiungi un file Dart al progetto

Per aggiungere un file Dart al progetto:

  • Fare clic con il pulsante destro del mouse sul progetto
  • Nuovo → Dart File
  • Immettere il nome dello script Dart

Di seguito è riportato uno screenshot dell'editor WebStorm:

Lo strumento dart2js

Il dart2jslo strumento compila il codice Dart in JavaScript. La compilazione del codice Dart su JS consente di eseguire lo script Dart sui browser che non supportano la VM Dart.

Lo strumento dart2js viene fornito come parte di Dart SDK e può essere trovato in /dartsdk/bin folder.

Per compilare Dart in JavaScript, digita il seguente comando nel terminale

dart2js - - out = <output_file>.js  <dart_script>.dart

Questo comando produce un file che contiene l'equivalente JavaScript del codice Dart. Un tutorial completo sull'utilizzo di questa utility è disponibile sul sito Web ufficiale di Dart.

La sintassi definisce un insieme di regole per la scrittura di programmi. Ogni specifica del linguaggio definisce la propria sintassi. Un programma Dart è composto da:

  • Variabili e operatori
  • Classes
  • Functions
  • Espressioni e costrutti di programmazione
  • Processi decisionali e costrutti di ciclo
  • Comments
  • Librerie e pacchetti
  • Typedefs
  • Strutture dati rappresentate come collezioni / generici

Il tuo primo codice freccette

Cominciamo con il tradizionale esempio "Hello World":

main() { 
   print("Hello World!"); 
}

Il main()funzione è un metodo predefinito in Dart. Questo metodo funge da punto di ingresso per l'applicazione. Uno script Dart necessita dimain() metodo di esecuzione. print() è una funzione predefinita che stampa la stringa o il valore specificato sullo standard output, ovvero il terminale.

L'output del codice precedente sarà:

Hello World!

Esegui un programma di freccette

Puoi eseguire un programma Dart in due modi:

  • Tramite il terminal
  • Tramite l'IDE di WebStorm

Tramite il Terminal

Per eseguire un programma Dart tramite il terminale:

  • Vai al percorso del progetto corrente
  • Digita il seguente comando nella finestra Terminale
dart file_name.dart

Tramite l'IDE di WebStorm

Per eseguire un programma Dart tramite l'IDE WebStorm -

  • Fare clic con il pulsante destro del mouse sul file di script Dart sull'IDE. (Il file dovrebbe contenere l'estensionemain() funzione per abilitare l'esecuzione)

  • Clicca sul ‘Run <file_name>’opzione. Di seguito è riportato uno screenshot dello stesso:

In alternativa è possibile fare clic sul

pulsante o utilizzare la scorciatoiaCtrl+Shift+F10 per eseguire lo script Dart.

Opzioni della riga di comando di Dart

Le opzioni della riga di comando Dart vengono utilizzate per modificare l'esecuzione dello script Dart. Le opzioni comuni della riga di comando per Dart includono quanto segue:

Suor n Opzione e descrizione della riga di comando
1 -c or --c

Abilita sia le asserzioni che i controlli del tipo (modalità controllata).

2 --version

Visualizza le informazioni sulla versione della VM.

3 --packages <path>

Specifica il percorso del file di configurazione della risoluzione del pacchetto.

4 -p <path>

Specifica dove trovare le librerie importate. Questa opzione non può essere utilizzata con --packages.

5 -h or --help

Visualizza la guida.

Abilitazione della modalità selezionata

I programmi Dart funzionano in due modalità:

  • Modalità selezionata
  • Modalità di produzione (predefinita)

Si consiglia di eseguire la VM Dart in formato checked modedurante lo sviluppo e il test, poiché aggiunge avvisi ed errori per aiutare lo sviluppo e il processo di debug. La modalità selezionata impone vari controlli come il controllo del tipo, ecc. Per attivare la modalità selezionata, aggiungere l'opzione -c o –-checked prima del nome del file di script durante l'esecuzione dello script.

Tuttavia, per garantire prestazioni ottimali durante l'esecuzione dello script, si consiglia di eseguire lo script nel file production mode.

Considera quanto segue Test.dart file di script -

void main() { 
   int n = "hello"; 
   print(n); 
}

Esegui lo script inserendo -

dart Test.dart

Sebbene ci sia una mancata corrispondenza del tipo, lo script viene eseguito correttamente quando la modalità selezionata è disattivata. Lo script produrrà il seguente output:

hello

Ora prova a eseguire lo script con l'opzione "- - selezionata" o "-c" -

dart -c Test.dart

O,

dart - - checked Test.dart

La VM Dart genererà un errore che indica che c'è una mancata corrispondenza del tipo.

Unhandled exception: 
type 'String' is not a subtype of type 'int' of 'n' where 
   String is from dart:core 
   int is from dart:core 
#0  main (file:///C:/Users/Administrator/Desktop/test.dart:3:9) 
#1  _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart :261) 
#2  _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

Identificatori in Dart

Gli identificatori sono nomi dati agli elementi in un programma come variabili, funzioni ecc. Le regole per gli identificatori sono:

Gli identificatori possono includere sia caratteri che cifre. Tuttavia, l'identificatore non può iniziare con una cifra.

  • Gli identificatori non possono includere simboli speciali ad eccezione del carattere di sottolineatura (_) o del simbolo del dollaro ($).

  • Gli identificatori non possono essere parole chiave.

  • Devono essere unici.

  • Gli identificatori fanno distinzione tra maiuscole e minuscole.

  • Gli identificatori non possono contenere spazi.

Le seguenti tabelle elencano alcuni esempi di identificatori validi e non validi:

Identificatori validi Identificatori non validi
nome di battesimo Var
nome di battesimo nome di battesimo
num1 nome di battesimo
$ risultato 1numero

Parole chiave in Dart

Le parole chiave hanno un significato speciale nel contesto di una lingua. La tabella seguente elenca alcune parole chiave in Dart.

astratto 1 Continua falso nuovo Questo
come 1 predefinito finale nullo gettare
asserire differito 1 finalmente operatore 1 vero
asincrono 2 fare per parte 1 provare
asincrono * 2 dinamico 1 ottieni 1 rilanciare typedef 1
attendi 2 altro Se ritorno var
rompere enum attrezzi 1 impostare 1 vuoto
Astuccio esportazione 1 importazione 1 statico 1 mentre
catturare esterno 1 in super con
classe si estende è interruttore resa 2
const fabbrica 1 libreria 1 sincronizzazione * 2 rendimento * 2

Spazi vuoti e interruzioni di riga

Dart ignora gli spazi, le tabulazioni e le nuove righe che appaiono nei programmi. Puoi usare spazi, tabulazioni e nuove righe liberamente nel tuo programma e sei libero di formattare e far rientrare i tuoi programmi in un modo ordinato e coerente che renda il codice facile da leggere e capire.

Dart fa distinzione tra maiuscole e minuscole

Dart distingue tra maiuscole e minuscole. Ciò significa che Dart distingue tra caratteri maiuscoli e minuscoli.

Le dichiarazioni terminano con un punto e virgola

Ogni riga di istruzione è chiamata istruzione. Ogni istruzione dart deve terminare con un punto e virgola (;). Una singola riga può contenere più istruzioni. Tuttavia, queste istruzioni devono essere separate da un punto e virgola.

Commenti in Dart

I commenti sono un modo per migliorare la leggibilità di un programma. I commenti possono essere utilizzati per includere informazioni aggiuntive su un programma come l'autore del codice, suggerimenti su una funzione / costrutto ecc. I commenti vengono ignorati dal compilatore.

Dart supporta i seguenti tipi di commenti:

  • Single-line comments ( // ) - Qualsiasi testo compreso tra un "//" e la fine di una riga viene trattato come un commento

  • Multi-line comments (/* */) - Questi commenti possono estendersi su più righe.

Esempio

// this is single line comment  
  
/* This is a   
   Multi-line comment  
*/

Programmazione orientata agli oggetti in Dart

Dart è un linguaggio orientato agli oggetti. L'orientamento agli oggetti è un paradigma di sviluppo software che segue la modellazione del mondo reale. Object Orientation considera un programma come una raccolta di oggetti che comunicano tra loro tramite meccanismi chiamati metodi.

  • Object- Un oggetto è una rappresentazione in tempo reale di qualsiasi entità. Come per la spilla Grady, ogni oggetto deve avere tre caratteristiche:

    • State - descritto dagli attributi di un oggetto.

    • Behavior - descrive come agirà l'oggetto.

    • Identity - un valore univoco che distingue un oggetto da un insieme di simili oggetti simili.

  • Class- Una classe in termini di OOP è un modello per la creazione di oggetti. Una classe incapsula i dati per l'oggetto.

  • Method - I metodi facilitano la comunicazione tra gli oggetti.

Esempio: freccette e orientamento dell'oggetto

class TestClass {   
   void disp() {     
      print("Hello World"); 
   } 
}  
void main() {   
   TestClass c = new TestClass();   
   c.disp();  
}

L'esempio precedente definisce una classe TestClass. La classe ha un metododisp(). Il metodo stampa la stringa "Hello World" sul terminale. La nuova parola chiave crea un oggetto della classe. L'oggetto richiama il metododisp().

Il codice dovrebbe produrre quanto segue output -

Hello World

Una delle caratteristiche fondamentali di un linguaggio di programmazione è l'insieme dei tipi di dati che supporta. Questi sono i tipi di valori che possono essere rappresentati e manipolati in un linguaggio di programmazione.

Il linguaggio Dart supporta i seguenti tipi:

  • Numbers
  • Strings
  • Booleans
  • Lists
  • Maps

Numeri

I numeri in Dart vengono utilizzati per rappresentare i letterali numerici. Il Number Dart è disponibile in due gusti:

  • Integer- I valori interi rappresentano valori non frazionari, ovvero valori numerici senza punto decimale. Ad esempio, il valore "10" è un numero intero. I letterali interi vengono rappresentati utilizzando ilint parola chiave.

  • Double- Dart supporta anche valori numerici frazionari cioè valori con punti decimali. Il tipo di dati Double in Dart rappresenta un numero a virgola mobile a 64 bit (precisione doppia). Ad esempio, il valore "10.10". La parola chiavedouble viene utilizzato per rappresentare valori letterali in virgola mobile.

stringhe

Le stringhe rappresentano una sequenza di caratteri. Ad esempio, se dovessi memorizzare alcuni dati come nome, indirizzo ecc., Dovrebbe essere utilizzato il tipo di dati stringa. Una stringa Dart è una sequenza di unità di codice UTF-16.Runes sono usati per rappresentare una sequenza di unità di codice UTF-32.

La parola chiave Stringviene utilizzato per rappresentare stringhe letterali. I valori stringa sono incorporati tra virgolette singole o doppie.

Booleano

Il tipo di dati booleano rappresenta i valori booleani true e false. Dart utilizza l'estensionebool parola chiave per rappresentare un valore booleano.

Elenco e mappa

L'elenco e la mappa dei tipi di dati vengono utilizzati per rappresentare una raccolta di oggetti. UNListè un gruppo ordinato di oggetti. Il tipo di dati List in Dart è sinonimo del concetto di array in altri linguaggi di programmazione. IlMapil tipo di dati rappresenta un insieme di valori come coppie chiave-valore. Ildart: core library consente la creazione e la manipolazione di queste raccolte tramite rispettivamente le classi List e Map predefinite.

Il tipo dinamico

Dart è un linguaggio digitato facoltativamente. Se il tipo di una variabile non è specificato esplicitamente, il tipo della variabile èdynamic. Ildynamic la parola chiave può anche essere utilizzata esplicitamente come annotazione di tipo.

Una variabile è "uno spazio con nome nella memoria" che memorizza i valori. In altre parole, funge da contenitore per i valori in un programma. I nomi delle variabili sono chiamati identificatori. Di seguito sono riportate le regole di denominazione per un identificatore:

  • Gli identificatori non possono essere parole chiave.

  • Gli identificatori possono contenere alfabeti e numeri.

  • Gli identificatori non possono contenere spazi e caratteri speciali, tranne il carattere di sottolineatura (_) e il segno del dollaro ($).

  • I nomi delle variabili non possono iniziare con un numero.

Digitare Sintassi

Una variabile deve essere dichiarata prima di essere utilizzata. Dart utilizza la parola chiave var per ottenere lo stesso risultato. La sintassi per dichiarare una variabile è la seguente:

var name = 'Smith';

Tutte le variabili in dart memorizzano un riferimento al valore anziché contenere il valore. La variabile chiamata nome contiene un riferimento a un oggetto String con un valore "Smith".

Dart supporta type-checkinganteponendo al nome della variabile il tipo di dati. Il controllo del tipo garantisce che una variabile contenga solo dati specifici per un tipo di dati. La sintassi per lo stesso è data di seguito:

String name = 'Smith'; 
int num = 10;

Considera il seguente esempio:

void main() { 
   String name = 1; 
}

Lo snippet di cui sopra risulterà in un avviso poiché il valore assegnato alla variabile non corrisponde al tipo di dati della variabile.

Produzione

Warning: A value of type 'String' cannot be assigned to a variable of type 'int'

Tutte le variabili non inizializzate hanno un valore iniziale di null. Questo perché Dart considera tutti i valori come oggetti. L'esempio seguente illustra lo stesso:

void main() { 
   int num; 
   print(num); 
}

Produzione

Null

La parola chiave dinamica

Le variabili dichiarate senza un tipo statico vengono dichiarate implicitamente come dinamiche. Le variabili possono essere dichiarate anche utilizzando la parola chiave dinamica al posto della parola chiave var.

Il seguente esempio illustra lo stesso.

void main() { 
   dynamic x = "tom"; 
   print(x);  
}

Produzione

tom

Finale e Cost

Il final e constvengono utilizzate per dichiarare le costanti. Dart impedisce di modificare i valori di una variabile dichiarata utilizzando la parola chiave final o const. Queste parole chiave possono essere utilizzate insieme al tipo di dati della variabile o al posto divar parola chiave.

Il constla parola chiave viene utilizzata per rappresentare una costante del tempo di compilazione. Variabili dichiarate utilizzando ilconst le parole chiave sono implicitamente finali.

Sintassi: parola chiave finale

final variable_name

O

final data_type  variable_name

Sintassi: parola chiave const

const variable_name

O

const data_type variable_name

Esempio: parola chiave finale

void main() { 
   final val1 = 12; 
   print(val1); 
}

Produzione

12

Esempio: parola chiave const

void main() { 
   const pi = 3.14; 
   const area = pi*12*12; 
   print("The output is ${area}"); 
}

L'esempio precedente dichiara due costanti, pi e area, usando il constparola chiave. Ilarea il valore della variabile è una costante del tempo di compilazione.

Produzione

The output is 452.15999999999997

Note - Solo constle variabili possono essere utilizzate per calcolare una costante di tempo di compilazione. Le costanti in fase di compilazione sono costanti i cui valori verranno determinati in fase di compilazione

Esempio

Dart genera un'eccezione se si tenta di modificare le variabili dichiarate con l'estensione finalo la parola chiave const. L'esempio fornito di seguito illustra lo stesso:

void main() { 
   final v1 = 12; 
   const v2 = 13; 
   v2 = 12; 
}

Il codice sopra riportato genererà il seguente errore come output -

Unhandled exception: 
cannot assign to final variable 'v2='.  
NoSuchMethodError: cannot assign to final variable 'v2=' 
#0  NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:178) 
#1      main (file: Test.dart:5:3) 
#2    _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261) 
#3    _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

Un'espressione è un tipo speciale di istruzione che restituisce un valore. Ogni espressione è composta da:

  • Operands - Rappresenta i dati

  • Operator - Definisce come verranno elaborati gli operandi per produrre un valore.

Considera la seguente espressione: "2 + 3". In questa espressione, 2 e 3 sonooperands e il simbolo "+" (più) è il operator.

In questo capitolo discuteremo gli operatori disponibili in Dart.

  • Operatori aritmetici
  • Uguaglianza e operatori relazionali
  • Operatori di test di tipo
  • Operatori bit per bit
  • Operatori di assegnazione
  • Operatori logici

Operatori aritmetici

La tabella seguente mostra gli operatori aritmetici supportati da Dart.

Mostra esempi

Suor n Operatori e significato
1 +

Inserisci

2

Sottrarre

3 -expr

Meno unario, noto anche come negazione (inverte il segno dell'espressione)

4 *

Moltiplicare

5 /

Dividere

6 ~/

Dividi, restituendo un risultato intero

7 %

Ottieni il resto di una divisione intera (modulo)

8 ++

Incremento

9 --

Decremento

Uguaglianza e operatori relazionali

Gli operatori relazionali verificano o definiscono il tipo di relazione tra due entità. Gli operatori relazionali restituiscono un valore booleano, ovvero vero / falso.

Supponiamo che il valore di A sia 10 e B sia 20.

Mostra esempi

Operatore Descrizione Esempio
> Più grande di (A> B) è False
< Minore di (A <B) è vero
> = Maggiore o uguale a (A> = B) è False
<= Minore o uguale a (A <= B) è vero
== Uguaglianza (A == B) è False
! = Non uguale (A! = B) è vero

Operatori di test di tipo

Questi operatori sono utili per controllare i tipi in fase di esecuzione.

Mostra esempi

Operatore Senso
è Vero se l'oggetto ha il tipo specificato
è! Falso se l'oggetto ha il tipo specificato

Operatori bit per bit

La tabella seguente elenca gli operatori bit per bit disponibili in Dart e il loro ruolo:

Mostra esempi

Operatore Descrizione Esempio
Bitwise AND a & b Restituisce uno in ciascuna posizione di bit per la quale i bit corrispondenti di entrambi gli operandi sono uno.
OR bit per bit a | b Restituisce uno in ogni posizione di bit per cui i bit corrispondenti di uno o entrambi gli operandi sono uno.
Bitwise XOR a ^ b Restituisce uno in ciascuna posizione di bit per cui i bit corrispondenti di uno ma non di entrambi gli operandi sono uno.
Bitwise NON ~ a Inverte i bit del suo operando.
Tasto maiuscolo di sinistra a ≪ b Sposta a nella rappresentazione binaria b (<32) bit a sinistra, spostandosi in zero da destra.
Segno di propagazione del cambio a destra a ≫ b Sposta a nella rappresentazione binaria b (<32) bit a destra, scartando i bit spostati.

Operatori di assegnazione

La tabella seguente elenca gli operatori di assegnazione disponibili in Dart.

Mostra esempi

Suor n Operatore e descrizione
1 =(Simple Assignment )

Assegna i valori dall'operando del lato destro all'operando del lato sinistro

Ex: C = A + B assegnerà il valore di A + B a C

2 ??=

Assegna il valore solo se la variabile è nulla

3 +=(Add and Assignment)

Aggiunge l'operando destro all'operando sinistro e assegna il risultato all'operando sinistro.

Ex: C + = A è equivalente a C = C + A

4 ─=(Subtract and Assignment)

Sottrae l'operando destro dall'operando sinistro e assegna il risultato all'operando sinistro.

Ex: C - = A è equivalente a C = C - A

5 *=(Multiply and Assignment)

Moltiplica l'operando destro con l'operando sinistro e assegna il risultato all'operando sinistro.

Ex: C * = A è equivalente a C = C * A

6 /=(Divide and Assignment)

Divide l'operando di sinistra con l'operando di destra e assegna il risultato all'operando di sinistra.

Note - La stessa logica si applica agli operatori Bitwise, quindi diventeranno ≪ =, ≫ =, ≫ =, ≫ =, | = e ^ =.

Operatori logici

Gli operatori logici vengono utilizzati per combinare due o più condizioni. Gli operatori logici restituiscono un valore booleano. Supponiamo che il valore della variabile A sia 10 e B sia 20.

Mostra esempi

Operatore Descrizione Esempio
&&

And - L'operatore restituisce true solo se tutte le espressioni specificate restituiscono true

(A> 10 && B> 10) è False.
||

OR - L'operatore restituisce true se almeno una delle espressioni specificate restituisce true

(A> 10 || B> 10) è vero.
!

NOT- L'operatore restituisce l'inverso del risultato dell'espressione. Ad esempio:! (7> 5) restituisce false

! (A> 10) è vero.

Espressioni condizionali

Dart ha due operatori che consentono di valutare espressioni che altrimenti potrebbero richiedere istruzioni ifelse:

condizione ? expr1: expr2

Se la condizione è vera, l'espressione valuta expr1(e ne restituisce il valore); in caso contrario, valuta e restituisce il valore diexpr2.

expr1 ?? expr2

Se expr1non è nullo, restituisce il suo valore; in caso contrario, valuta e restituisce il valore diexpr2

Esempio

L'esempio seguente mostra come utilizzare l'espressione condizionale in Dart:

void main() { 
   var a = 10; 
   var res = a > 12 ? "value greater than 10":"value lesser than or equal to 10"; 
   print(res); 
}

Produrrà il seguente output:

value lesser than or equal to 10

Esempio

Facciamo un altro esempio:

void main() { 
   var a = null; 
   var b = 12; 
   var res = a ?? b; 
   print(res); 
}

Produrrà il seguente output:

12

A volte, alcune istruzioni richiedono l'esecuzione ripetuta. I loop sono un modo ideale per fare lo stesso. Un ciclo rappresenta un insieme di istruzioni che devono essere ripetute. Nel contesto di un ciclo, una ripetizione è definita come un fileiteration.

La figura seguente illustra la classificazione dei loop:

Cominciamo la discussione con Definite Loops. Un ciclo il cui numero di iterazioni è definito / fisso è definito come un filedefinite loop.

Suor n Loop e descrizione
1 per loop

Il forloop è un'implementazione di un ciclo definito. Il ciclo for esegue il blocco di codice per un numero di volte specificato. Può essere utilizzato per iterare su un insieme fisso di valori, come un array

2 per ... in Loop

Il ciclo for ... in viene utilizzato per scorrere le proprietà di un oggetto.

Andando avanti, discutiamo ora dei loop indefiniti. Un ciclo indefinito viene utilizzato quando il numero di iterazioni in un ciclo è indeterminato o sconosciuto. I cicli indefiniti possono essere implementati usando -

Suor n Loop e descrizione
1 mentre Loop

Il ciclo while esegue le istruzioni ogni volta che la condizione specificata restituisce true. In altre parole, il ciclo valuta la condizione prima che il blocco di codice venga eseguito.

2 fare ... mentre Loop

Il ciclo do ... while è simile al ciclo while tranne per il fatto che il ciclo do ... while non valuta la condizione per la prima volta che il ciclo viene eseguito.

Passiamo ora e discutiamo di Loop Control Statements di Dart.

Suor n Dichiarazione di controllo e descrizione
1 Istruzione break

Il breakviene utilizzata per estrarre il controllo da un costrutto. Utilizzandobreakin un ciclo fa sì che il programma esca dal ciclo. Di seguito è riportato un esempio dibreak dichiarazione.

2 continua Dichiarazione

Il continue l'istruzione salta le istruzioni successive nell'iterazione corrente e riporta il controllo all'inizio del ciclo.

Utilizzo di etichette per controllare il flusso

UN labelè semplicemente un identificatore seguito da due punti (:) applicato a un'istruzione o a un blocco di codice. È possibile utilizzare un'etichetta conbreak e continue per controllare il flusso in modo più preciso.

Non sono consentite interruzioni di riga tra i file ‘continue’ o ‘break’dichiarazione e il nome dell'etichetta. Inoltre, non dovrebbero esserci altre istruzioni tra il nome di un'etichetta e un ciclo associato.

Esempio: etichetta con interruzione

void main() { 
   outerloop: // This is the label name 
   
   for (var i = 0; i < 5; i++) { 
      print("Innerloop: ${i}"); innerloop: for (var j = 0; j < 5; j++) { if (j > 3 ) break ; // Quit the innermost loop if (i == 2) break innerloop; // Do the same thing if (i == 4) break outerloop; // Quit the outer loop print("Innerloop: ${j}"); 
      } 
   } 
}

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

Innerloop: 0
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 1
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 2
Innerloop: 3
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 4

Esempio: etichetta con continua

void main() { 
   outerloop: // This is the label name 
   
   for (var i = 0; i < 3; i++) { 
      print("Outerloop:${i}"); for (var j = 0; j < 5; j++) { if (j == 3){ continue outerloop; } print("Innerloop:${j}"); 
      } 
   } 
}

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

Outerloop: 0 
Innerloop: 0 
Innerloop: 1 
Innerloop: 2 

Outerloop: 1 
Innerloop: 0 
Innerloop: 1 
Innerloop: 2 

Outerloop: 2 
Innerloop: 0 
Innerloop: 1 
Innerloop: 2

Un costrutto condizionale / decisionale valuta una condizione prima che le istruzioni vengano eseguite.

I costrutti condizionali in Dart sono classificati nella tabella seguente.

Suor n Dichiarazione e descrizione
1 if dichiarazione

Un if L'istruzione consiste in un'espressione booleana seguita da una o più istruzioni.

2 If ... Else Statement

Un if può essere seguito da un optional elsebloccare. Ilelse block verrà eseguito se l'espressione booleana testata da if block restituisce false.

3 altrimenti ... se Ladder

Il else…if ladderè utile per testare più condizioni. Di seguito è riportata la sintassi dello stesso.

4 switch ... case Statement

L'istruzione switch valuta un'espressione, abbina il valore dell'espressione a una clausola case ed esegue le istruzioni associate a quel caso.

I numeri delle freccette possono essere classificati come:

  • int- Numero intero di dimensioni arbitrarie. Ilint il tipo di dati viene utilizzato per rappresentare i numeri interi.

  • double- Numeri in virgola mobile a 64 bit (precisione doppia), come specificato dallo standard IEEE 754. Ildouble il tipo di dati viene utilizzato per rappresentare i numeri frazionari

Il num il tipo è ereditato dal int e doubletipi. Ildart core library consente numerose operazioni su valori numerici.

La sintassi per la dichiarazione di un numero è la seguente:

int var_name;      // declares an integer variable 
double var_name;   // declares a double variable

Esempio

void main() {
   // declare an integer
   int num1 = 10;             
     
   // declare a double value
   double num2 = 10.50;  

   // print the values
   print(num1);
   print(num2);
}

Produrrà il seguente output:

10 
10.5

Note - Il Dart VM genererà un'eccezione se i valori frazionari sono assegnati a variabili intere.

Analisi

Il parse()la funzione statica consente di analizzare una stringa contenente un valore letterale numerico in un numero. La figura seguente mostra la stessa cosa:

void main() { 
   print(num.parse('12')); 
   print(num.parse('10.91')); 
}

Il codice sopra risulterà nel seguente output:

12 
10.91

La funzione di analisi genera un file FormatExceptionse viene passato un valore diverso dai numeri. Il codice seguente mostra come passare un valore alfanumerico aparse() funzione.

Esempio

void main() { 
   print(num.parse('12A')); 
   print(num.parse('AAAA')); 
}

Il codice sopra risulterà nel seguente output:

Unhandled exception: 
FormatException: 12A 
#0 num.parse (dart:core/num.dart:446) 
#1 main (file:///D:/Demos/numbers.dart:4:13) 
#2 _startIsolate.<anonymous closure> (dart:isolatepatch/isolate_patch.dart:261) 
#3 _RawReceivePortImpl._handleMessage (dart:isolatepatch/isolate_patch.dart:148)

Proprietà numero

La tabella seguente elenca le proprietà supportate dai numeri Dart.

Suor n Proprietà e descrizione
1 codice hash

Restituisce un codice hash per un valore numerico.

2 isFinite

Vero se il numero è finito; in caso contrario, false.

3 isInfinite

Vero se il numero è infinito positivo o infinito negativo; in caso contrario, false.

4 isNan

Vero se il numero è il doppio valore Non un numero; in caso contrario, false.

5 isNegative

Vero se il numero è negativo; in caso contrario, false.

6 cartello

Restituisce meno uno, zero o più uno a seconda del segno e del valore numerico del numero.

7 è anche

Restituisce vero se il numero è un numero pari.

8 isOdd

Restituisce vero se il numero è un numero dispari.

Metodi numerici

Di seguito è riportato un elenco di metodi comunemente usati supportati da numeri:

Suor n Metodo e descrizione
1 addominali

Restituisce il valore assoluto del numero.

2 ceil

Restituisce il numero intero minimo non inferiore al numero.

3 confrontare con

Confronta questo con un altro numero.

4 Pavimento

Restituisce il numero intero più grande non maggiore del numero corrente.

5 resto

Restituisce il resto troncato dopo aver diviso i due numeri.

6 Il giro

Restituisce il numero intero più vicino ai numeri correnti.

7 raddoppiare

Restituisce il doppio equivalente del numero.

8 toInt

Restituisce l'equivalente intero del numero.

9

Restituisce la rappresentazione equivalente in stringa del numero.

10 troncare

Restituisce un numero intero dopo aver scartato qualsiasi cifra frazionaria.

Il tipo di dati String rappresenta una sequenza di caratteri. Una stringa Dart è una sequenza di unità di codice UTF 16.

I valori stringa in Dart possono essere rappresentati utilizzando virgolette singole, doppie o triple. Le stringhe a riga singola vengono rappresentate utilizzando virgolette singole o doppie. Le virgolette triple vengono utilizzate per rappresentare stringhe su più righe.

La sintassi per rappresentare i valori di stringa in Dart è la seguente:

Sintassi

String  variable_name = 'value'  

OR  

String  variable_name = ''value''  

OR  

String  variable_name = '''line1 
line2'''  

OR  

String  variable_name= ''''''line1 
line2''''''

L'esempio seguente illustra l'uso del tipo di dati String in Dart.

void main() { 
   String str1 = 'this is a single line string'; 
   String str2 = "this is a single line string"; 
   String str3 = '''this is a multiline line string'''; 
   String str4 = """this is a multiline line string"""; 
   
   print(str1);
   print(str2); 
   print(str3); 
   print(str4); 
}

Produrrà quanto segue Output -

this is a single line string 
this is a single line string 
this is a multiline line string 
this is a multiline line string

Le stringhe sono immutabili. Tuttavia, le stringhe possono essere soggette a varie operazioni e la stringa risultante può essere memorizzata come nuovo valore.

Interpolazione di stringhe

Il processo di creazione di una nuova stringa aggiungendo un valore a una stringa statica viene definito come concatenation o interpolation. In altre parole, è il processo di aggiunta di una stringa a un'altra stringa.

L'operatore più (+) è un meccanismo comunemente usato per concatenare / interpolare stringhe.

Esempio 1

void main() { 
   String str1 = "hello"; 
   String str2 = "world"; 
   String res = str1+str2; 
   
   print("The concatenated string : ${res}"); 
}

Produrrà quanto segue output -

The concatenated string : Helloworld

Esempio 2

È possibile utilizzare "$ {}" per interpolare il valore di un'espressione Dart all'interno di stringhe. Il seguente esempio illustra lo stesso.

void main() { 
   int n=1+1; 
   
   String str1 = "The sum of 1 and 1 is ${n}"; print(str1); String str2 = "The sum of 2 and 2 is ${2+2}"; 
   print(str2); 
}

Produrrà quanto segue output -

The sum of 1 and 1 is 2 
The sum of 2 and 2 is 4

Proprietà stringa

Le proprietà elencate nella tabella seguente sono tutte di sola lettura.

Suor n Proprietà e descrizione
1 codeUnits

Restituisce un elenco non modificabile delle unità di codice UTF-16 di questa stringa.

2 è vuoto

Restituisce vero se questa stringa è vuota.

3 Lunghezza

Restituisce la lunghezza della stringa inclusi spazio, tabulazione e caratteri di nuova riga.

Metodi per manipolare le stringhe

La classe String in dart: core libraryfornisce anche metodi per manipolare le stringhe. Alcuni di questi metodi sono riportati di seguito:

Suor n Metodi e descrizione
1 toLowerCase ()

Converte tutti i caratteri di questa stringa in minuscolo.

2 toUpperCase ()

Converte tutti i caratteri di questa stringa in maiuscolo.

3 trim ()

Restituisce la stringa senza spazi iniziali e finali.

4 confrontare con()

Confronta questo oggetto con un altro.

5 sostituisci tutto()

Sostituisce tutte le sottostringhe che corrispondono al modello specificato con un dato valore.

6 Diviso()

Divide la stringa in corrispondenza delle corrispondenze del delimitatore specificato e restituisce un elenco di sottostringhe.

7 sottostringa ()

Restituisce la sottostringa di questa stringa che si estende da startIndex, incluso, a endIndex, esclusivo.

8 accordare()

Restituisce una rappresentazione di stringa di questo oggetto.

9 codeUnitAt ()

Restituisce l'unità di codice UTF-16 a 16 bit all'indice specificato.

Dart fornisce un supporto integrato per il tipo di dati booleano. Il tipo di dati booleano in DART supporta solo due valori: vero e falso. La parola chiave bool viene utilizzata per rappresentare un valore letterale booleano in DART.

La sintassi per la dichiarazione di una variabile booleana in DART è la seguente:

bool var_name = true;  
OR  
bool var_name = false

Esempio

void main() { 
   bool test; 
   test = 12 > 5; 
   print(test); 
}

Produrrà quanto segue output -

true

Esempio

A differenza di JavaScript, il tipo di dati booleano riconosce come vero solo il vero letterale. Qualsiasi altro valore è considerato falso. Considera il seguente esempio:

var str = 'abc'; 
if(str) { 
   print('String is not empty'); 
} else { 
   print('Empty String'); 
}

Lo snippet sopra, se eseguito in JavaScript, stamperà il messaggio "La stringa non è vuota" poiché il costrutto if restituirà true se la stringa non è vuota.

Tuttavia, in Dart, strviene convertito in false come str! = true . Quindi lo snippet stamperà il messaggio 'Empty String' (se eseguito in modalità non selezionata).

Esempio

Lo snippet sopra se eseguito in checkedmode genererà un'eccezione. Lo stesso è illustrato di seguito -

void main() { 
   var str = 'abc'; 
   if(str) { 
      print('String is not empty'); 
   } else { 
      print('Empty String'); 
   } 
}

Produrrà quanto segue output, in Checked Mode -

Unhandled exception: 
type 'String' is not a subtype of type 'bool' of 'boolean expression' where 
   String is from dart:core 
   bool is from dart:core  
#0 main (file:///D:/Demos/Boolean.dart:5:6) 
#1 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261) 
#2 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

Produrrà quanto segue output, in Unchecked Mode -

Empty String

Note - Il WebStorm IDE viene eseguito in modalità selezionata, per impostazione predefinita.

Una raccolta molto comunemente usata nella programmazione è un file array. Dart rappresenta gli array sotto forma diListoggetti. UNListè semplicemente un gruppo ordinato di oggetti. Ildart:core library fornisce la classe List che consente la creazione e la manipolazione di elenchi.

La rappresentazione logica di un elenco in Dart è fornita di seguito:

  • test_list - è l'identificatore che fa riferimento alla raccolta.

  • L'elenco contiene i valori 12, 13 e 14. I blocchi di memoria che contengono questi valori sono noti come elements.

  • Ogni elemento nell'elenco è identificato da un numero univoco chiamato index. L'indice inizia dazero e si estende fino a n-1 dove nè il numero totale di elementi nell'elenco. L'indice è anche denominatosubscript.

Gli elenchi possono essere classificati come:

  • Elenco a lunghezza fissa
  • Elenco coltivabile

Parliamo ora di questi due tipi di lists in dettaglio.

Elenco a lunghezza fissa

La lunghezza di un elenco a lunghezza fissa non può cambiare in fase di esecuzione. La sintassi per la creazione di un elenco di lunghezza fissa è la seguente:

Step 1 − Declaring a list

La sintassi per la dichiarazione di un elenco di lunghezza fissa è fornita di seguito:

var list_name = new List(initial_size)

La sintassi precedente crea un elenco delle dimensioni specificate. L'elenco non può aumentare o diminuire in fase di esecuzione. Qualsiasi tentativo di ridimensionare l'elenco comporterà un'eccezione.

Step 2 − Initializing a list

La sintassi per inizializzare un elenco è la seguente:

lst_name[index] = value;

Esempio

void main() { 
   var lst = new List(3); 
   lst[0] = 12; 
   lst[1] = 13; 
   lst[2] = 11; 
   print(lst); 
}

Produrrà quanto segue output -

[12, 13, 11]

Elenco coltivabile

La lunghezza di un elenco espandibile può cambiare in fase di esecuzione. La sintassi per dichiarare e inizializzare un elenco espandibile è la seguente:

Step 1 − Declaring a List

var list_name = [val1,val2,val3]   
--- creates a list containing the specified values  
OR  
var list_name = new List() 
--- creates a list of size zero

Step 2 − Initializing a List

L'indice / pedice viene utilizzato per fare riferimento all'elemento che dovrebbe essere popolato con un valore. La sintassi per inizializzare un elenco è la seguente:

list_name[index] = value;

Esempio

L'esempio seguente mostra come creare un elenco di 3 elementi.

void main() { 
   var num_list = [1,2,3]; 
   print(num_list); 
}

Produrrà quanto segue output -

[1, 2, 3]

Esempio

L'esempio seguente crea un elenco di lunghezza zero utilizzando l'estensione empty List() constructor. Iladd() funzione in List class viene utilizzata per aggiungere dinamicamente elementi all'elenco.

void main() { 
   var lst = new List(); 
   lst.add(12); 
   lst.add(13); 
   print(lst); 
}

Produrrà quanto segue output -

[12, 13]

Proprietà elenco

La tabella seguente elenca alcune proprietà comunemente utilizzate di List classe in dart:core library.

Suor n Metodi e descrizione
1 primo

Restituisce il caso del primo elemento.

2 isEmpty

Returns true if the collection has no elements.

3 isNotEmpty

Returns true if the collection has at least one element.

4 length

Returns the size of the list.

5 last

Returns the last element in the list.

6 reversed

Returns an iterable object containing the lists values in the reverse order.

7 Single

Checks if the list has only one element and returns it.

In this chapter, we will discuss how to carry out some basic operations on Lists, such as −

Sr.No Basic Operation & Description
1 Inserting Elements into a List

Mutable Lists can grow dynamically at runtime. The List.add() function appends the specified value to the end of the List and returns a modified List object.

2 Updating a list

Lists in Dart can be updated by −

  • Updating The Index
  • Using the List.replaceRange() function
3 Removing List items

The following functions supported by the List class in the dart:core library can be used to remove the item(s) in a List.

The Map object is a simple key/value pair. Keys and values in a map may be of any type. A Map is a dynamic collection. In other words, Maps can grow and shrink at runtime.

Maps can be declared in two ways −

  • Using Map Literals
  • Using a Map constructor

Declaring a Map using Map Literals

To declare a map using map literals, you need to enclose the key-value pairs within a pair of curly brackets "{ }".

Here is its syntax

var identifier = { key1:value1, key2:value2 [,…..,key_n:value_n] }

Dichiarazione di una mappa utilizzando un costruttore di mappe

Per dichiarare una mappa utilizzando un costruttore di mappe, abbiamo due passaggi. Per prima cosa, dichiara la mappa e poi inizializza la mappa.

Il syntax per declare a map è il seguente -

var identifier = new Map()

Ora, usa la seguente sintassi per initialize the map -

map_name[key] = value

Esempio: Map Literal

void main() { 
   var details = {'Usrname':'tom','Password':'pass@123'}; 
   print(details); 
}

Produrrà quanto segue output -

{Usrname: tom, Password: pass@123}

Esempio: aggiunta di valori ai letterali di mappatura in fase di runtime

void main() { 
   var details = {'Usrname':'tom','Password':'pass@123'}; 
   details['Uid'] = 'U1oo1'; 
   print(details); 
}

Produrrà quanto segue output -

{Usrname: tom, Password: pass@123, Uid: U1oo1}

Esempio: Map Constructor

void main() { 
   var details = new Map(); 
   details['Usrname'] = 'admin'; 
   details['Password'] = 'admin@123'; 
   print(details); 
}

Produrrà quanto segue output -

{Usrname: admin, Password: admin@123}

Note - Un valore di mappa può essere qualsiasi oggetto incluso NULL.

Mappa - Proprietà

Il Map class nel pacchetto dart: core definisce le seguenti proprietà:

Suor n Proprietà e descrizione
1 Chiavi

Restituisce un oggetto iterabile che rappresenta le chiavi

2 Valori

Restituisce un oggetto iterabile che rappresenta i valori

3 Lunghezza

Restituisce la dimensione della mappa

4 è vuoto

Restituisce vero se la mappa è una mappa vuota

5 non è vuoto

Restituisce vero se la mappa è una mappa vuota

Mappa - Funzioni

Di seguito sono riportate le funzioni comunemente utilizzate per manipolare le mappe in Dart.

Suor n Nome e descrizione della funzione
1 Aggiungi tutto()

Aggiunge tutte le coppie chiave-valore dell'altro a questa mappa.

2 chiaro()

Rimuove tutte le coppie dalla mappa.

3 rimuovere()

Rimuove la chiave e il valore associato, se presente, dalla mappa.

4 per ciascuno()

Applica f a ciascuna coppia chiave-valore della mappa.

I simboli in Dart sono nomi di stringa dinamici e opachi utilizzati per riflettere i metadati di una libreria. In poche parole, i simboli sono un modo per memorizzare la relazione tra una stringa leggibile dall'uomo e una stringa ottimizzata per essere utilizzata dai computer.

La riflessione è un meccanismo per ottenere i metadati di un tipo in fase di esecuzione come il numero di metodi in una classe, il numero di costruttori che ha o il numero di parametri in una funzione. È anche possibile richiamare un metodo del tipo caricato in fase di esecuzione.

In Dart Reflection sono disponibili classi specifiche in dart:mirrorspacchetto. Questa libreria funziona sia nelle applicazioni web che nelle applicazioni a riga di comando.

Sintassi

Symbol obj = new Symbol('name');  
// expects a name of class or function or library to reflect

Il name deve essere un nome di membro Dart pubblico, un nome di costruttore pubblico o un nome di libreria valido.

Esempio

Considera il seguente esempio. Il codice dichiara una classeFoo in biblioteca foo_lib. La classe definisce i metodim1, m2, e m3.

Foo.dart

library foo_lib;   
// libarary name can be a symbol   

class Foo {         
   // class name can be a symbol  
   m1() {        
      // method name can be a symbol 
      print("Inside m1"); 
   } 
   m2() { 
      print("Inside m2"); 
   } 
   m3() { 
      print("Inside m3"); 
   } 
}

Viene caricato il codice seguente Foo.dartlibreria e cerca la classe Foo, con l'aiuto del tipo Symbol. Poiché stiamo riflettendo i metadati dalla libreria sopra, il codice importadart:mirrors biblioteca.

FooSymbol.dart

import 'dart:core'; 
import 'dart:mirrors'; 
import 'Foo.dart';  

main() { 
   Symbol lib = new Symbol("foo_lib");   
   //library name stored as Symbol 
   
   Symbol clsToSearch = new Symbol("Foo");  
   // class name stored as Symbol  
   
   if(checkIf_classAvailableInlibrary(lib, clsToSearch))  
   // searches Foo class in foo_lib library 
      print("class found.."); 
}  
   
bool checkIf_classAvailableInlibrary(Symbol libraryName, Symbol className) { 
   MirrorSystem mirrorSystem = currentMirrorSystem(); 
   LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName); 
      
   if (libMirror != null) { 
      print("Found Library"); 
      print("checkng...class details.."); 
      print("No of classes found is : ${libMirror.declarations.length}"); 
      libMirror.declarations.forEach((s, d) => print(s));  
         
      if (libMirror.declarations.containsKey(className)) return true; 
      return false; 
   } 
}

Notare che la riga libMirror.declarations.forEach ((s, d) => print (s)); itererà su ogni dichiarazione nella libreria in fase di esecuzione e stampa le dichiarazioni come tipo diSymbol.

Questo codice dovrebbe produrre quanto segue output -

Found Library 
checkng...class details.. 
No of classes found is : 1 
Symbol("Foo") // class name displayed as symbol  
class found.

Esempio: visualizzare il numero di metodi di istanza di una classe

Consideriamo ora la visualizzazione del numero di metodi di istanza in una classe. La classe predefinitaClassMirror ci aiuta a ottenere lo stesso risultato.

import 'dart:core'; 
import 'dart:mirrors'; 
import 'Foo.dart';  

main() { 
   Symbol lib = new Symbol("foo_lib"); 
   Symbol clsToSearch = new Symbol("Foo");  
   reflect_InstanceMethods(lib, clsToSearch); 
}  
void reflect_InstanceMethods(Symbol libraryName, Symbol className) { 
   MirrorSystem mirrorSystem = currentMirrorSystem(); 
   LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName); 
   
   if (libMirror != null) { 
      print("Found Library"); 
      print("checkng...class details.."); 
      print("No of classes found is : ${libMirror.declarations.length}"); 
      libMirror.declarations.forEach((s, d) => print(s));  
      
      if (libMirror.declarations.containsKey(className)) print("found class");
      ClassMirror classMirror = libMirror.declarations[className]; 
      
      print("No of instance methods found is ${classMirror.instanceMembers.length}");
      classMirror.instanceMembers.forEach((s, v) => print(s)); 
   } 
}

Questo codice dovrebbe produrre quanto segue output -

Found Library 
checkng...class details.. 
No of classes found is : 1 
Symbol("Foo") 
found class 
No of instance methods found is 8 
Symbol("==") 
Symbol("hashCode") 
Symbol("toString") 
Symbol("noSuchMethod") 
Symbol("runtimeType") 
Symbol("m1") 
Symbol("m2") 
Symbol("m3")

Converti simbolo in stringa

Puoi convertire il nome di un tipo come la classe o la libreria memorizzata in un simbolo in una stringa usando MirrorSystemclasse. Il codice seguente mostra come convertire un simbolo in una stringa.

import 'dart:mirrors'; 
void main(){ 
   Symbol lib = new Symbol("foo_lib"); 
   String name_of_lib = MirrorSystem.getName(lib); 
   
   print(lib); 
   print(name_of_lib); 
}

Dovrebbe produrre quanto segue output -

Symbol("foo_lib")   

foo_lib

Le stringhe sono una sequenza di caratteri. Dart rappresenta le stringhe come una sequenza di unità di codice Unicode UTF-16. Unicode è un formato che definisce un valore numerico univoco per ogni lettera, cifra e simbolo.

Poiché una stringa Dart è una sequenza di unità di codice UTF-16, i valori Unicode a 32 bit all'interno di una stringa vengono rappresentati utilizzando una sintassi speciale. UNrune è un numero intero che rappresenta un punto di codice Unicode.

La classe String in dart:core la libreria fornisce meccanismi per l'accesso runes. È possibile accedere alle unità / rune del codice stringa in tre modi:

  • Utilizzo della funzione String.codeUnitAt ()
  • Utilizzo della proprietà String.codeUnits
  • Utilizzo della proprietà String.runes

Funzione String.codeUnitAt ()

È possibile accedere alle unità di codice in una stringa tramite i relativi indici. Restituisce l'unità di codice UTF-16 a 16 bit all'indice specificato.

Sintassi

String.codeUnitAt(int index);

Esempio

import 'dart:core'; 
void main(){ 
   f1(); 
} 
f1() { 
   String x = 'Runes'; 
   print(x.codeUnitAt(0)); 
}

Produrrà quanto segue output -

82

Proprietà String.codeUnits

Questa proprietà restituisce un elenco non modificabile delle unità di codice UTF-16 della stringa specificata.

Sintassi

String. codeUnits;

Esempio

import 'dart:core';  
void main(){ 
   f1(); 
}  
f1() { 
   String x = 'Runes'; 
   print(x.codeUnits); 
}

Produrrà quanto segue output -

[82, 117, 110, 101, 115]

Proprietà String.runes

Questa proprietà restituisce un iterabile di punti di codice Unicode di this string.Runes estende iterabile.

Sintassi

String.runes

Esempio

void main(){ 
   "A string".runes.forEach((int rune) { 
      var character=new String.fromCharCode(rune); 
      print(character); 
   });  
}

Produrrà quanto segue output -

A 
s 
t 
r 
i 
n 
g

I punti di codice Unicode sono generalmente espressi come \uXXXX, dove XXXX è un valore esadecimale di 4 cifre. Per specificare più o meno di 4 cifre esadecimali, inserire il valore tra parentesi graffe. Si può usare il costruttore della classe Runes nella libreria dart: core per lo stesso.

Esempio

main() { 
   Runes input = new Runes(' \u{1f605} '); 
   print(new String.fromCharCodes(input)); 
}

Produrrà quanto segue output -

Un'enumerazione viene utilizzata per definire valori costanti denominati. Un tipo enumerato viene dichiarato utilizzando ilenum parola chiave.

Sintassi

enum enum_name {  
   enumeration list 
}

Dove,

  • L'enum_name specifica il nome del tipo di enumerazione
  • L' elenco di enumerazione è un elenco di identificatori separati da virgole

Ciascuno dei simboli nell'elenco di enumerazione rappresenta un valore intero, uno maggiore del simbolo che lo precede. Per impostazione predefinita, il valore del primo simbolo di enumerazione è 0.

Per esempio

enum Status { 
   none, 
   running, 
   stopped, 
   paused 
}

Esempio

enum Status { 
   none, 
   running, 
   stopped, 
   paused 
}  
void main() { 
   print(Status.values); 
   Status.values.forEach((v) => print('value: $v, index: ${v.index}')); print('running: ${Status.running}, ${Status.running.index}'); print('running index: ${Status.values[1]}'); 
}

Produrrà quanto segue output -

[Status.none, Status.running, Status.stopped, Status.paused] 
value: Status.none, index: 0 
value: Status.running, index: 1 
value: Status.stopped, index: 2 
value: Status.paused, index: 3 
running: Status.running, 1 
running index: Status.running

Le funzioni sono gli elementi costitutivi del codice leggibile, gestibile e riutilizzabile. Una funzione è un insieme di istruzioni per eseguire un'attività specifica. Le funzioni organizzano il programma in blocchi logici di codice. Una volta definite, le funzioni possono essere chiamate per accedere al codice. Ciò rende il codice riutilizzabile. Inoltre, le funzioni facilitano la lettura e la manutenzione del codice del programma.

Una dichiarazione di funzione indica al compilatore il nome, il tipo restituito e i parametri di una funzione. Una definizione di funzione fornisce il corpo effettivo della funzione.

Suor n Funzioni e descrizione
1 Definizione di una funzione

Una definizione di funzione specifica cosa e come verrà eseguita un'attività specifica.

2 Chiamare una funzione

Una funzione deve essere chiamata in modo da eseguirla.

3 Restituzione di funzioni

Le funzioni possono anche restituire valore insieme al controllo, al chiamante.

4 Funzione parametrizzata

I parametri sono un meccanismo per passare valori alle funzioni.

Parametri opzionali

I parametri opzionali possono essere utilizzati quando gli argomenti non devono essere obbligatoriamente passati per l'esecuzione di una funzione. Un parametro può essere contrassegnato come facoltativo aggiungendo un punto interrogativo al suo nome. Il parametro facoltativo dovrebbe essere impostato come ultimo argomento in una funzione.

Abbiamo tre tipi di parametri opzionali in Dart:

Suor n Parametro e descrizione
1 Parametro posizionale opzionale

Per specificare parametri posizionali opzionali, utilizzare le parentesi quadre [].

2 Parametro denominato facoltativo

A differenza dei parametri posizionali, il nome del parametro deve essere specificato durante il passaggio del valore. La parentesi graffa {} può essere utilizzata per specificare parametri denominati facoltativi.

3 Parametri opzionali con valori predefiniti

I parametri delle funzioni possono anche essere assegnati valori per impostazione predefinita. Tuttavia, tali parametri possono anche essere passati in modo esplicito valori.

Funzioni ricorsive del dardo

La ricorsione è una tecnica per iterare su un'operazione avendo una funzione chiamata a se stessa ripetutamente finché non arriva a un risultato. La ricorsione viene applicata al meglio quando è necessario chiamare ripetutamente la stessa funzione con parametri diversi dall'interno di un ciclo.

Esempio

void main() { 
   print(factorial(6));
}  
factorial(number) { 
   if (number <= 0) {         
      // termination case 
      return 1; 
   } else { 
      return (number * factorial(number - 1));    
      // function invokes itself 
   } 
}

Dovrebbe produrre quanto segue output -

720

Funzioni Lambda

Le funzioni Lambda sono un meccanismo conciso per rappresentare le funzioni. Queste funzioni sono anche chiamate funzioni freccia.

Sintassi

[return_type]function_name(parameters)=>expression;

Esempio

void main() { 
   printMsg(); 
   print(test()); 
}  
printMsg()=>
print("hello"); 

int test()=>123;                       
// returning function

Dovrebbe produrre quanto segue output -

hello 123

Un interfacedefinisce la sintassi a cui deve aderire qualsiasi entità. Le interfacce definiscono un insieme di metodi disponibili su un oggetto. Dart non ha una sintassi per la dichiarazione delle interfacce. Le dichiarazioni di classe sono esse stesse interfacce in Dart.

Classesdovrebbe usare la parola chiave implements per poter usare un'interfaccia. È obbligatorio che la classe di implementazione fornisca un'implementazione concreta di tutte le funzioni dell'interfaccia implementata. In altre parole, una classe deve ridefinire ogni funzione nell'interfaccia che desidera implementare.

Sintassi: implementazione di un'interfaccia

class identifier implements interface_name

Esempio

Nel seguente programma dichiariamo una classe Printer. IlConsolePrinter class implementa la dichiarazione di interfaccia implicita per Printerclasse. Ilmain la funzione crea un oggetto della ConsolePrinter classe utilizzando il newparola chiave. Questo oggetto viene utilizzato per richiamare la funzioneprint_data definito nel ConsolePrinter classe.

void main() { 
   ConsolePrinter cp= new ConsolePrinter(); 
   cp.print_data(); 
}  
class Printer { 
   void print_data() { 
      print("__________Printing Data__________"); 
   } 
}  
class ConsolePrinter implements Printer { 
   void print_data() {  
      print("__________Printing to Console__________"); 
   } 
}

Dovrebbe produrre quanto segue output -

__________Printing to Console__________

Implementazione di più interfacce

Una classe può implementare più interfacce. Le interfacce sono separate da una virgola. Ilsyntax per lo stesso è dato di seguito -

class identifier implements interface-1,interface_2,interface_4…….

Il seguente example mostra come implementare più interfacce in Dart -

void main() { 
   Calculator c = new Calculator(); 
   print("The gross total : ${c.ret_tot()}"); print("Discount :${c.ret_dis()}"); 
}  
class Calculate_Total { 
   int ret_tot() {} 
}  
class Calculate_Discount { 
   int ret_dis() {} 
}
class Calculator  implements Calculate_Total,Calculate_Discount { 
   int ret_tot() { 
      return 1000; 
   } 
   int ret_dis() { 
      return 50; 
   } 
}

Dovrebbe produrre quanto segue output -

The gross total: 1000 
Discount:50

Dart è un linguaggio orientato agli oggetti. Supporta funzionalità di programmazione orientata agli oggetti come classi, interfacce, ecc. Aclassin termini di OOP è un modello per la creazione di oggetti. UNclassincapsula i dati per l'oggetto. Dart fornisce il supporto integrato per questo concetto chiamatoclass.

Dichiarazione di una classe

Utilizzare il class parola chiave per dichiarare un file classa Dart. Una definizione di classe inizia con la parola chiave class seguita daclass name; e il corpo di classe racchiuso da un paio di parentesi graffe. La sintassi per lo stesso è data di seguito:

Sintassi

class class_name {  
   <fields> 
   <getters/setters> 
   <constructors> 
   <functions> 
}

Il classla parola chiave è seguita dal nome della classe. Le regole per gli identificatori devono essere considerate durante la denominazione di una classe.

Una definizione di classe può includere quanto segue:

  • Fields- Un campo è una qualsiasi variabile dichiarata in una classe. I campi rappresentano i dati relativi agli oggetti.

  • Setters and Getters- Consente al programma di inizializzare e recuperare i valori dei campi di una classe. Un getter / setter predefinito è associato a ogni classe. Tuttavia, quelli di default possono essere sovrascritti definendo esplicitamente un setter / getter.

  • Constructors - responsabile dell'allocazione della memoria per gli oggetti della classe.

  • Functions- Le funzioni rappresentano le azioni che un oggetto può intraprendere. A volte sono anche indicati come metodi.

Questi componenti messi insieme sono chiamati data members della classe.

Esempio: dichiarazione di una classe

class Car {  
   // field 
   String engine = "E1001";  
   
   // function 
   void disp() { 
      print(engine); 
   } 
}

L'esempio dichiara una classe Car. La classe ha un campo denominatoengine. Ildisp() è una semplice funzione che stampa il valore del campo engine.

Creazione di istanza della classe

Per creare un'istanza della classe, usa il newparola chiave seguita dal nome della classe. La sintassi per lo stesso è data di seguito:

Sintassi

var object_name = new class_name([ arguments ])
  • Il new la parola chiave è responsabile dell'istanza.

  • Il lato destro dell'espressione richiama il costruttore. Al costruttore dovrebbero essere passati valori se è parametrizzato.

Esempio: creazione di un'istanza di una classe

var obj = new Car("Engine 1")

Accesso ad attributi e funzioni

È possibile accedere agli attributi e alle funzioni di una classe tramite l'oggetto. Utilizzare il '.' notazione punto (chiamata comeperiod) per accedere ai membri dati di una classe.

//accessing an attribute 
obj.field_name  

//accessing a function 
obj.function_name()

Esempio

Dai un'occhiata al seguente esempio per capire come accedere ad attributi e funzioni in Dart -

void main() { 
   Car c= new Car(); 
   c.disp(); 
}  
class Car {  
   // field 
   String engine = "E1001";  
   
   // function 
   void disp() { 
      print(engine); 
   } 
}

Il output del codice sopra è il seguente -

E1001

Costruttori di freccette

Un costruttore è una funzione speciale della classe responsabile dell'inizializzazione delle variabili della classe. Dart definisce un costruttore con lo stesso nome di quello della classe. Un costruttore è una funzione e quindi può essere parametrizzato. Tuttavia, a differenza di una funzione, i costruttori non possono avere un tipo restituito. Se non dichiari un costruttore, un file predefinitono-argument constructor è previsto per te.

Sintassi

Class_name(parameter_list) { 
   //constructor body 
}

Esempio

L'esempio seguente mostra come utilizzare i costruttori in Dart:

void main() { 
   Car c = new Car('E1001'); 
} 
class Car { 
   Car(String engine) { 
      print(engine); 
   } 
}

Dovrebbe produrre quanto segue output -

E1001

Costruttori denominati

Dart fornisce named constructors per abilitare una definizione di classe multiple constructors. La sintassi dei costruttori con nome è la seguente:

Sintassi: definizione del costruttore

Class_name.constructor_name(param_list)

Esempio

L'esempio seguente mostra come utilizzare i costruttori con nome in Dart:

void main() {           
   Car c1 = new Car.namedConst('E1001');                                       
   Car c2 = new Car(); 
}           
class Car {                   
   Car() {                           
      print("Non-parameterized constructor invoked");
   }                                   
   Car.namedConst(String engine) { 
      print("The engine is : ${engine}");    
   }                               
}

Dovrebbe produrre quanto segue output -

The engine is : E1001 
Non-parameterized constructor invoked

La parola chiave this

Il thisparola chiave si riferisce all'istanza corrente della classe. Qui, il nome del parametro e il nome del campo della classe coincidono. Quindi, per evitare ambiguità, il campo della classe è preceduto dathisparola chiave. L'esempio seguente spiega lo stesso:

Esempio

Il seguente esempio spiega come utilizzare this parola chiave in Dart -

void main() { 
   Car c1 = new Car('E1001'); 
}  
class Car { 
   String engine; 
   Car(String engine) { 
      this.engine = engine; 
      print("The engine is : ${engine}"); 
   } 
}

Dovrebbe produrre quanto segue output -

The engine is : E1001

Classe Dart ─ Getters e Setter

Getters e Setters, chiamato anche come accessors e mutators, consentono al programma di inizializzare e recuperare i valori dei campi di classe rispettivamente. Getter o funzioni di accesso vengono definiti utilizzandogetparola chiave. I setter oi mutatori vengono definiti utilizzando ilset parola chiave.

Un getter / setter predefinito è associato a ogni classe. Tuttavia, quelli di default possono essere sovrascritti definendo esplicitamente un setter / getter. Un getter non ha parametri e restituisce un valore e il setter ha un parametro e non restituisce un valore.

Sintassi: definizione di un getter

Return_type  get identifier 
{ 
}

Sintassi: definizione di un setter

set identifier 
{ 
}

Esempio

Il seguente esempio mostra come puoi usare getters e setters in una classe Dart -

class Student { 
   String name; 
   int age; 
    
   String get stud_name { 
      return name; 
   } 
    
   void set stud_name(String name) { 
      this.name = name; 
   } 
   
   void set stud_age(int age) { 
      if(age<= 0) { 
        print("Age should be greater than 5"); 
      }  else { 
         this.age = age; 
      } 
   } 
   
   int get stud_age { 
      return age;     
   } 
}  
void main() { 
   Student s1 = new Student(); 
   s1.stud_name = 'MARK'; 
   s1.stud_age = 0; 
   print(s1.stud_name); 
   print(s1.stud_age); 
}

Questo codice di programma dovrebbe produrre quanto segue output -

Age should be greater than 5 
MARK 
Null

Ereditarietà di classe

Dart supporta il concetto di ereditarietà che è la capacità di un programma di creare nuove classi da una classe esistente. La classe estesa per creare classi più recenti è chiamata classe genitore / super classe. Le classi appena create sono chiamate classi figlio / sotto.

Una classe eredita da un'altra classe utilizzando la parola chiave "extends". Child classes inherit all properties and methods except constructors from the parent class.

Sintassi

class child_class_name extends parent_class_name

Note - Dart non supporta l'ereditarietà multipla.

Esempio: ereditarietà della classe

Nell'esempio seguente, stiamo dichiarando una classe Shape. La classe è estesa dalCircleclasse. Poiché esiste una relazione di ereditarietà tra le classi, la classe figlia, ovvero la classeCar ottiene un accesso implicito al membro dati della sua classe genitore.

void main() { 
   var obj = new Circle(); 
   obj.cal_area(); 
}  
class Shape { 
   void cal_area() { 
      print("calling calc area defined in the Shape class"); 
   } 
}  
class Circle extends Shape {}

Dovrebbe produrre quanto segue output -

calling calc area defined in the Shape class

Tipi di ereditarietà

L'ereditarietà può essere dei seguenti tre tipi:

  • Single - Ogni classe può estendersi al massimo da una classe genitore.

  • Multiple- Una classe può ereditare da più classi. Dart non supporta l'ereditarietà multipla.

  • Multi-level - Una classe può ereditare da un'altra classe figlia.

Esempio

L'esempio seguente mostra come funziona l'ereditarietà multilivello:

void main() { 
   var obj = new Leaf(); 
   obj.str = "hello"; 
   print(obj.str); 
}  
class Root { 
   String str; 
}  
class Child extends Root {}  
class Leaf extends Child {}  
//indirectly inherits from Root by virtue of inheritance

La classe Leafderiva gli attributi dalle classi Root e Child in virtù dell'ereditarietà multi-livello. Suooutput è il seguente -

hello

Dart - Ereditarietà della classe e sostituzione del metodo

L'override del metodo è un meccanismo mediante il quale la classe figlia ridefinisce un metodo nella sua classe genitore. L'esempio seguente illustra lo stesso:

Esempio

void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   void m1(int a){ print("value of a ${a}");} } class Child extends Parent { @override void m1(int b) { print("value of b ${b}"); 
   } 
}

Dovrebbe produrre quanto segue output -

value of b 12

Il numero e il tipo dei parametri della funzione devono corrispondere durante l'override del metodo. In caso di mancata corrispondenza nel numero di parametri o nel loro tipo di dati, il compilatore Dart genera un errore. La seguente illustrazione spiega lo stesso:

import 'dart:io'; 
void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   void m1(int a){ print("value of a ${a}");} } class Child extends Parent { @override void m1(String b) { print("value of b ${b}");
   } 
}

Dovrebbe produrre quanto segue output -

value of b 12

La parola chiave statica

Il static la parola chiave può essere applicata ai membri di dati di una classe, ad esempio fields e methods. Una variabile statica mantiene i propri valori fino al termine dell'esecuzione del programma. I membri statici sono referenziati dal nome della classe.

Esempio

class StaticMem { 
   static int num;  
   static disp() { 
      print("The value of num is ${StaticMem.num}")  ; 
   } 
}  
void main() { 
   StaticMem.num = 12;  
   // initialize the static variable } 
   StaticMem.disp();   
   // invoke the static method 
}

Dovrebbe produrre quanto segue output -

The value of num is 12

La super parola chiave

Il superviene utilizzata per fare riferimento al genitore immediato di una classe. La parola chiave può essere utilizzata per fare riferimento alla versione super class di avariable, property, o method. L'esempio seguente illustra lo stesso:

Esempio

void main() { 
   Child c = new Child(); 
   c.m1(12); 
} 
class Parent { 
   String msg = "message variable from the parent class"; 
   void m1(int a){ print("value of a ${a}");} 
} 
class Child extends Parent { 
   @override 
   void m1(int b) { 
      print("value of b ${b}"); super.m1(13); print("${super.msg}")   ; 
   } 
}

Dovrebbe produrre quanto segue output -

value of b 12 
value of a 13 
message variable from the parent class

La programmazione orientata agli oggetti definisce un oggetto come "qualsiasi entità con un confine definito". Un oggetto ha quanto segue:

  • State- Descrive l'oggetto. I campi di una classe rappresentano lo stato dell'oggetto.

  • Behavior - Descrive cosa può fare un oggetto.

  • Identity- Un valore univoco che distingue un oggetto da un insieme di altri oggetti simili. Due o più oggetti possono condividere lo stato e il comportamento ma non l'identità.

L'operatore del periodo (.) viene utilizzato insieme all'oggetto per accedere ai membri dei dati di una classe.

Esempio

Dart rappresenta i dati sotto forma di oggetti. Ogni classe in Dart estende la classe Object. Di seguito è riportato un semplice esempio di creazione e utilizzo di un oggetto.

class Student { 
   void test_method() { 
      print("This is a  test method"); 
   } 
   
   void test_method1() { 
      print("This is a  test method1"); 
   } 
}  
void main()    { 
   Student s1 = new Student(); 
   s1.test_method(); 
   s1.test_method1(); 
}

Dovrebbe produrre quanto segue output -

This is a test method 
This is a test method1

L'operatore Cascade (..)

L'esempio precedente richiama i metodi nella classe. Tuttavia, ogni volta che viene chiamata una funzione, è richiesto un riferimento all'oggetto. Ilcascade operator può essere usato come scorciatoia nei casi in cui è presente una sequenza di invocazioni.

L'operatore a cascata (..) può essere utilizzato per emettere una sequenza di chiamate tramite un oggetto. L'esempio sopra può essere riscritto nel modo seguente.

class Student { 
   void test_method() { 
      print("This is a  test method"); 
   } 
   
   void test_method1() { 
      print("This is a  test method1"); 
   } 
}  
void main() { 
   new Student() 
   ..test_method() 
   ..test_method1(); 
}

Dovrebbe produrre quanto segue output -

This is a test method 
This is a test method1

Il metodo toString ()

Questa funzione restituisce una rappresentazione di stringa di un oggetto. Dai un'occhiata al seguente esempio per capire come usare iltoString metodo.

void main() { 
   int n = 12; 
   print(n.toString()); 
}

Dovrebbe produrre quanto segue output -

12

Dart, a differenza di altri linguaggi di programmazione, non supporta gli array. Le raccolte Dart possono essere utilizzate per replicare strutture di dati come un array. La libreria dart: core e altre classi abilitano il supporto della raccolta negli script Dart.

Le raccolte di freccette possono essere sostanzialmente classificate come:

Suor n Raccolta e descrizione delle freccette
1 Elenco

Una lista è semplicemente un gruppo ordinato di oggetti. Ildart:core library fornisce la classe List che consente la creazione e la manipolazione di elenchi.

  • Fixed Length List - La lunghezza dell'elenco non può cambiare in fase di esecuzione.

  • Growable List - La lunghezza dell'elenco può cambiare in fase di esecuzione.

2 Impostato

Set rappresenta una raccolta di oggetti in cui ogni oggetto può essere presente una sola volta. La libreria dart: core fornisce la classe Set per implementare lo stesso.

3 Mappe

L'oggetto Map è una semplice coppia chiave / valore. Chiavi e valori in una mappa possono essere di qualsiasi tipo. Una mappa è una raccolta dinamica. In altre parole, Maps può crescere e ridursi in fase di esecuzione. La classe Map nella libreria dart: core fornisce il supporto per lo stesso.

4 Coda

Una coda è una raccolta che può essere manipolata da entrambe le estremità. Le code sono utili quando si desidera creare una raccolta first-in, first-out. In poche parole, una coda inserisce i dati da un'estremità ed elimina da un'altra estremità. I valori vengono rimossi / letti nell'ordine in cui sono stati inseriti.

Iterazione delle raccolte

La classe Iterator di dart:corela libreria consente un facile attraversamento della raccolta. Ogni collezione ha un fileiteratorproprietà. Questa proprietà restituisce un iteratore che punta agli oggetti nella raccolta.

Esempio

L'esempio seguente illustra l'attraversamento di una raccolta utilizzando un oggetto iteratore.

import 'dart:collection'; 
void main() { 
   Queue numQ = new Queue(); 
   numQ.addAll([100,200,300]);  
   Iterator i= numQ.iterator; 
   
   while(i.moveNext()) { 
      print(i.current); 
   } 
}

Il moveNext()la funzione restituisce un valore booleano che indica se è presente una voce successiva. Ilcurrent La proprietà dell'oggetto iteratore restituisce il valore dell'oggetto a cui punta attualmente l'iteratore.

Questo programma dovrebbe produrre quanto segue output -

100 
200 
300

Dart è un file optionally typed language. Le raccolte in Dart sono eterogenee per impostazione predefinita. In altre parole, una singola raccolta Dart può ospitare valori di vari tipi. Tuttavia, è possibile creare una raccolta Dart per contenere valori omogenei. Il concetto di generici può essere utilizzato per ottenere lo stesso risultato.

L'utilizzo di Generics impone una restrizione sul tipo di dati dei valori che possono essere contenuti dalla raccolta. Tali raccolte vengono definite raccolte indipendenti dai tipi. La sicurezza dei tipi è una funzione di programmazione che garantisce che un blocco di memoria possa contenere solo dati di un tipo di dati specifico.

Tutte le raccolte Dart supportano l'implementazione dell'indipendenza dai tipi tramite generics. Una coppia di parentesi angolari contenente il tipo di dati viene utilizzata per dichiarare una raccolta indipendente dai tipi. La sintassi per la dichiarazione di una raccolta indipendente dai tipi è la seguente.

Sintassi

Collection_name <data_type> identifier= new Collection_name<data_type>

Di seguito sono riportate le implementazioni indipendenti dai tipi di List, Map, Set e Queue. Questa funzione è supportata anche da tutte le implementazioni dei tipi di raccolta sopra menzionati.

Esempio: elenco generico

void main() { 
   List <String> logTypes = new List <String>(); 
   logTypes.add("WARNING"); 
   logTypes.add("ERROR"); 
   logTypes.add("INFO");  
   
   // iterating across list 
   for (String type in logTypes) { 
      print(type); 
   } 
}

Dovrebbe produrre quanto segue output -

WARNING 
ERROR 
INFO

Un tentativo di inserire un valore diverso dal tipo specificato provocherà un errore di compilazione. Il seguente esempio lo illustra.

Esempio

void main() { 
   List <String> logTypes = new List <String>(); 
   logTypes.add(1); 
   logTypes.add("ERROR"); 
   logTypes.add("INFO"); 
  
   //iterating across list 
   for (String type in logTypes) { 
      print(type); 
   } 
}

Dovrebbe produrre quanto segue output -

1                                                                                     
ERROR                                                                             
INFO

Esempio: set generico

void main() { 
   Set <int>numberSet = new  Set<int>(); 
   numberSet.add(100); 
   numberSet.add(20); 
   numberSet.add(5); 
   numberSet.add(60);
   numberSet.add(70); 
   
   // numberSet.add("Tom"); 
   compilation error; 
   print("Default implementation  :${numberSet.runtimeType}");  
   
   for(var no in numberSet) { 
      print(no); 
   } 
}

Dovrebbe produrre quanto segue output -

Default implementation :_CompactLinkedHashSet<int> 
100 
20 
5 
60 
70

Esempio: coda generica

import 'dart:collection'; 
void main() { 
   Queue<int> queue = new Queue<int>(); 
   print("Default implementation ${queue.runtimeType}");  
   queue.addLast(10); 
   queue.addLast(20); 
   queue.addLast(30); 
   queue.addLast(40); 
   queue.removeFirst();  
   
   for(int no in queue){ 
      print(no); 
   } 
}

Dovrebbe produrre quanto segue output -

Default implementation ListQueue<int> 
20 
30 
40

Mappa generica

Una dichiarazione di mappa indipendente dai tipi specifica i tipi di dati di -

  • Il tasto
  • Il valore

Sintassi

Map <Key_type, value_type>

Esempio

void main() { 
   Map <String,String>m={'name':'Tom','Id':'E1001'}; 
   print('Map :${m}'); 
}

Dovrebbe produrre quanto segue output -

Map :{name: Tom, Id: E1001}

Un pacchetto è un meccanismo per incapsulare un gruppo di unità di programmazione. A volte le applicazioni potrebbero richiedere l'integrazione di alcune librerie o plug-in di terze parti. Ogni linguaggio ha un meccanismo per la gestione di pacchetti esterni come Maven o Gradle per Java, Nuget per .NET, npm per Node.js, ecc. Il gestore di pacchetti per Dart èpub.

Pub aiuta a installare i pacchetti nel repository. Il repository dei pacchetti ospitati può essere trovato suhttps://pub.dartlang.org/.

Il package metadata è definito in un file, pubsec.yaml. YAML è l'acronimo diYet Another Markup Language. Ilpub può essere utilizzato per scaricare tutte le varie librerie richieste da un'applicazione.

Ogni applicazione Dart ha un file pubspec.yaml file che contiene le dipendenze dell'applicazione da altre librerie e metadati di applicazioni come nome dell'applicazione, autore, versione e descrizione.

Il contenuto di un file pubspec.yaml il file dovrebbe assomigliare a questo -

name: 'vector_victor' 
version: 0.0.1 
description: An absolute bare-bones web app. 
... 
dependencies: browser: '>=0.10.0 <0.11.0'

L'importante pub commands sono i seguenti -

Suor n Comando e descrizione
1

‘pub get’

Aiuta a ottenere tutti i pacchetti da cui dipende la tua applicazione.

2

‘pub upgrade’

Aggiorna tutte le tue dipendenze a una versione più recente.

3

‘pub build’

Questo è usato per costruire la tua applicazione web e creerà una cartella di build, con tutti gli script correlati in essa.

4

‘pub help’

Questo ti darà aiuto per tutti i diversi comandi pub.

Se stai usando un IDE come WebStorm, puoi fare clic con il pulsante destro del mouse su pubspec.yaml per ottenere direttamente tutti i comandi -

Installazione di un pacchetto

Considera un esempio in cui un'applicazione deve analizzare xml. Dart XML è una libreria leggera, open source e stabile per l'analisi, l'esplorazione, l'interrogazione e la creazione di documenti XML.

I passaggi per raggiungere tale compito sono i seguenti:

Step 1 - Aggiungere quanto segue al file pubsec.yaml.

name: TestApp 
version: 0.0.1 
description: A simple console application. 
#dependencies: 
#  foo_bar: '>=1.0.0 <2.0.0' 
dependencies: https://mail.google.com/mail/u/0/images/cleardot.gif
xml:

Fare clic con il pulsante destro del mouse sul file pubsec.yamle ottieni le dipendenze. Questo attiverà internamente il filepub get command come mostrato di seguito.

I pacchetti scaricati ei relativi pacchetti dipendenti possono essere verificati nella cartella dei pacchetti.

Poiché l'installazione è stata completata ora, è necessario fare riferimento al file dart xmlnel progetto. La sintassi è la seguente:

import 'package:xml/xml.dart' as xml;

Leggi stringa XML

Per leggere la stringa XML e verificare l'input, Dart XML utilizza un file parse()metodo. La sintassi è la seguente:

xml.parse(String input):

Esempio: analisi dell'input stringa XML

L'esempio seguente mostra come analizzare l'input di stringhe XML:

import 'package:xml/xml.dart' as xml; 
void main(){ 
   print("xml"); 
   var bookshelfXml = '''<?xml version = "1.0"?> 
   <bookshelf> 
      <book> 
         <title lang = "english">Growing a Language</title> 
         <price>29.99</price> 
      </book> 
      
      <book> 
         <title lang = "english">Learning XML</title> 
         <price>39.95</price> 
      </book> 
      <price>132.00</price> 
   </bookshelf>'''; 
   
   var document = xml.parse(bookshelfXml); 
   print(document.toString()); 
}

Dovrebbe produrre quanto segue output -

xml 
<?xml version = "1.0"?><bookshelf> 
   <book> 
      <title lang = "english">Growing a Language</title> 
      <price>29.99</price> 
   </book> 

   <book> 
      <title lang = "english">Learning XML</title> 
      <price>39.95</price> 
   </book> 
   <price>132.00</price> 
</bookshelf>

Un'eccezione (o evento eccezionale) è un problema che si verifica durante l'esecuzione di un programma. Quando si verifica un'eccezione, il normale flusso del programma viene interrotto e il programma / applicazione termina in modo anomalo.

Le eccezioni Dart incorporate includono:

Suor n Eccezioni e descrizione
1

DeferredLoadException

Generato quando una libreria differita non viene caricata.

2

FormatException

Eccezione generata quando una stringa o altri dati non hanno un formato previsto e non possono essere analizzati o elaborati.

3

IntegerDivisionByZeroException

Lanciato quando un numero viene diviso per zero.

4

IOException

Classe base per tutte le eccezioni relative a Inupt-Output.

5

IsolateSpawnException

Lanciato quando non è possibile creare un isolato.

6

Timeout

Generato quando si verifica un timeout pianificato durante l'attesa di un risultato asincrono.

Ogni eccezione in Dart è un sottotipo della classe predefinita Exception. Le eccezioni devono essere gestite per impedire la chiusura improvvisa dell'applicazione.

I blocchi try / on / catch

Il tryblock incorpora codice che potrebbe eventualmente causare un'eccezione. Il blocco on viene utilizzato quando è necessario specificare il tipo di eccezione. Ilcatch block viene utilizzato quando il gestore necessita dell'oggetto eccezione.

Il try blocco deve essere seguito esattamente da uno on / catch blocco o uno finallyblocco (o uno di entrambi). Quando si verifica un'eccezione nel blocco try, il controllo viene trasferito al filecatch.

Il syntax per la gestione di un'eccezione è come indicato di seguito:

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // code for handling exception 
}  
catch Exception2 { 
   // code for handling exception 
}

Di seguito sono riportati alcuni punti da ricordare:

  • Uno snippet di codice può avere più di un blocco on / catch per gestire più eccezioni.

  • Il blocco on e il blocco catch si includono a vicenda, ovvero un blocco try può essere associato sia al blocco on che al blocco catch.

Il codice seguente illustra la gestione delle eccezioni in Dart -

Esempio: utilizzo del blocco ON

Il seguente programma divide due numeri rappresentati dalle variabili x e yrispettivamente. Il codice genera un'eccezione poiché tenta la divisione per zero. Ilon block contiene il codice per gestire questa eccezione.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
}

Dovrebbe produrre quanto segue output -

Cannot divide by zero

Esempio: utilizzo del blocco catch

Nell'esempio seguente, abbiamo utilizzato lo stesso codice di cui sopra. L'unica differenza è che il filecatch block(invece del blocco ON) qui contiene il codice per gestire l'eccezione. Il parametro dicatch contiene l'oggetto eccezione generato in fase di esecuzione.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {  
      res = x ~/ y; 
   }  
   catch(e) { 
      print(e); 
   } 
}

Dovrebbe produrre quanto segue output -

IntegerDivisionByZeroException

Esempio: su ... cattura

L'esempio seguente mostra come utilizzare il on...catch bloccare.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   }  
   on IntegerDivisionByZeroException catch(e) { 
      print(e); 
   } 
}

Dovrebbe produrre quanto segue output -

IntegerDivisionByZeroException

L'ultimo blocco

Il finallyblock include codice che dovrebbe essere eseguito indipendentemente dal verificarsi di un'eccezione. L'opzionalefinally block viene eseguito incondizionatamente dopo try/on/catch.

La sintassi per l'utilizzo di finally il blocco è il seguente -

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // exception handling code 
}  
catch Exception2 { 
   //  exception handling 
}  
finally { 
   // code that should always execute; irrespective of the exception 
}

L'esempio seguente illustra l'uso di finally bloccare.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
   finally { 
      print('Finally block executed'); 
   } 
}

Dovrebbe produrre quanto segue output -

Cannot divide by zero 
Finally block executed

Lanciare un'eccezione

Il throwla parola chiave viene utilizzata per sollevare esplicitamente un'eccezione. Un'eccezione sollevata dovrebbe essere gestita per impedire la chiusura improvvisa del programma.

Il syntax per sollevare un'eccezione esplicitamente è -

throw new Exception_name()

Esempio

L'esempio seguente mostra come utilizzare il throw parola chiave per generare un'eccezione -

main() { 
   try { 
      test_age(-2); 
   } 
   catch(e) { 
      print('Age cannot be negative'); 
   } 
}  
void test_age(int age) { 
   if(age<0) { 
      throw new FormatException(); 
   } 
}

Dovrebbe produrre quanto segue output -

Age cannot be negative

Eccezioni personalizzate

Come specificato sopra, ogni tipo di eccezione in Dart è un sottotipo della classe incorporata Exception. Dart consente di creare eccezioni personalizzate estendendo quelle esistenti. La sintassi per definire un'eccezione personalizzata è la seguente:

Sintassi: definizione dell'eccezione

class Custom_exception_Name implements Exception { 
   // can contain constructors, variables and methods 
}

Le eccezioni personalizzate dovrebbero essere sollevate in modo esplicito e le stesse dovrebbero essere gestite nel codice.

Esempio

L'esempio seguente mostra come definire e gestire un'eccezione personalizzata.

class AmtException implements Exception { 
   String errMsg() => 'Amount should be greater than zero'; 
}  
void main() { 
   try { 
      withdraw_amt(-1); 
   } 
   catch(e) { 
      print(e.errMsg()); 
   }  
finally { 
      print('Ending requested operation.....'); 
   } 
}  
void withdraw_amt(int amt) { 
   if (amt <= 0) { 
      throw new AmtException(); 
   } 
}

Nel codice sopra, stiamo definendo un'eccezione personalizzata, AmtException. Il codice solleva l'eccezione se l'importo passato non rientra nell'intervallo escluso. Ilmain funzione racchiude la chiamata della funzione nel file try...catch bloccare.

Il codice dovrebbe produrre quanto segue output -

Amount should be greater than zero 
Ending requested operation....

Di tanto in tanto, gli sviluppatori commettono errori durante la codifica. Un errore in un programma viene definito bug. Il processo di ricerca e correzione dei bug è chiamato debugging ed è una parte normale del processo di sviluppo. Questa sezione copre gli strumenti e le tecniche che possono aiutarti con le attività di debug.

L'editor WebStorm abilita i punti di interruzione e il debug passo passo. Il programma si interromperà nel punto in cui è collegato il punto di interruzione. Questa funzionalità è simile a ciò che ci si potrebbe aspettare dallo sviluppo di applicazioni Java o C #. È possibile osservare le variabili, sfogliare lo stack, passare e passare alle chiamate di metodi e funzioni, tutto dall'editor WebStorm.

Aggiunta di un punto di interruzione

Considera il seguente frammento di codice. (TestString.dart)

void main() { 
   int a = 10, b = 20, c = 5; 
   c = c * c * c; 
   
   print("$a + $b = ${a+b}"); 
   print("$a%$b = ${a%b}"); // Add a break point here print("$a*$b = ${a*b}"); 
   print("$a/$b = ${a/b}"); 
   print(c); 
}

Per add a breakpoint, fare clic sul margine sinistro per. Nella figura riportata di seguito, la riga numero 7 ha un punto di interruzione.

Run the program in debug mode. Nell'esploratore del progetto fare clic con il tasto destro sul programma dart nel nostro caso TestString.dart.

Una volta che il programma viene eseguito in modalità di debug, verrà visualizzata la finestra Debugger come mostrato nello screenshot seguente. La scheda Variabili mostra i valori delle variabili nel contesto corrente. Puoi aggiungere watcher per variabili specifiche e ascoltare le modifiche dei valori utilizzando la finestra di watch.

Step IntoL'icona della freccia (F7) nel menu di debug aiuta a eseguire il codice un'istruzione alla volta. Se i metodi principali chiamano una subroutine, anche questa andrà nel codice della subroutine.

Step over (F8): è simile a Step Into. La differenza di utilizzo si verifica quando l'istruzione corrente contiene una chiamata a una subroutine. Se il metodo principale chiama una subroutine, step over non eseguirà il drill nella subroutine. salterà la subroutine.

Step Out(Shift + F8): esegue le righe rimanenti di una funzione in cui si trova il punto di esecuzione corrente. L'istruzione successiva visualizzata è l'istruzione che segue la chiamata alla subroutine.

Dopo l'esecuzione in modalità debug, il programma fornisce quanto segue output -

10 + 20 = 30 
10 % 20 = 10 
10 * 20 = 200 
10 / 20 = 0.5 
125

UN typedef, o un alias del tipo di funzione, aiuta a definire i puntatori al codice eseguibile all'interno della memoria. In poche parole, atypedef può essere usato come un puntatore che fa riferimento a una funzione.

Di seguito sono riportati i passaggi da implementare typedefs in un programma Dart.

Step 1: Defining a typedef

UN typedefpuò essere usato per specificare una firma di funzione che vogliamo che funzioni specifiche corrispondano. Una firma di funzione è definita dai parametri di una funzione (inclusi i loro tipi). Il tipo restituito non fa parte della firma della funzione. La sua sintassi è la seguente.

typedef function_name(parameters)

Step 2: Assigning a Function to a typedef Variable

Una variabile di typedef può puntare a qualsiasi funzione che abbia la stessa firma di typedef. È possibile utilizzare la seguente firma per assegnare una funzione a un filetypedef variabile.

type_def  var_name = function_name

Step 3: Invoking a Function

Il typedefvariabile può essere utilizzata per invocare funzioni. Ecco come puoi invocare una funzione:

var_name(parameters)

Esempio

Facciamo ora un esempio per capirne di più typedef a Dart.

Inizialmente, definiamo un file typedef. Qui stiamo definendo una firma di funzione. La funzione richiederà due parametri di input del tipointeger. Il tipo restituito non fa parte della firma della funzione.

typedef ManyOperation(int firstNo , int secondNo); //function signature

Successivamente, definiamo le funzioni. Definire alcune funzioni con la stessa firma di funzione di quella diManyOperation typedef.

Add(int firstNo,int second){ 
   print("Add result is ${firstNo+second}"); 
}  
Subtract(int firstNo,int second){ 
   print("Subtract result is ${firstNo-second}"); } Divide(int firstNo,int second){ print("Add result is ${firstNo/second}"); 
}

Infine, invocheremo la funzione tramite typedef. Dichiarare una variabile del tipo ManyOperations. Assegna il nome della funzione alla variabile dichiarata.

ManyOperation oper ;  

//can point to any method of same signature 
oper = Add; 
oper(10,20); 
oper = Subtract; 
oper(30,20); 
oper = Divide; 
oper(50,5);

Il opervariabile può puntare a qualsiasi metodo che accetta due parametri interi. IlAddil riferimento della funzione è assegnato alla variabile. I typedef possono cambiare i riferimenti alle funzioni in fase di esecuzione

Mettiamo ora insieme tutte le parti e vediamo il programma completo.

typedef ManyOperation(int firstNo , int secondNo); 
//function signature  

Add(int firstNo,int second){ 
   print("Add result is ${firstNo+second}"); } Subtract(int firstNo,int second){ print("Subtract result is ${firstNo-second}"); 
}
Divide(int firstNo,int second){ 
   print("Divide result is ${firstNo/second}"); 
}  
Calculator(int a, int b, ManyOperation oper){ 
   print("Inside calculator"); 
   oper(a,b); 
}  
void main(){ 
   ManyOperation oper = Add; 
   oper(10,20); 
   oper = Subtract; 
   oper(30,20); 
   oper = Divide; 
   oper(50,5); 
}

Il programma dovrebbe produrre quanto segue output -

Add result is 30 
Subtract result is 10 
Divide result is 10.0

Note - Il codice precedente genererà un errore se il file typedef variabile cerca di puntare a una funzione con una diversa firma di funzione.

Esempio

Typedefspuò anche essere passato come parametro a una funzione. Considera il seguente esempio:

typedef ManyOperation(int firstNo , int secondNo);   //function signature 
Add(int firstNo,int second){ 
   print("Add result is ${firstNo+second}"); 
}  
Subtract(int firstNo,int second){
   print("Subtract result is ${firstNo-second}"); } Divide(int firstNo,int second){ print("Divide result is ${firstNo/second}"); 
}  
Calculator(int a,int b ,ManyOperation oper){ 
   print("Inside calculator"); 
   oper(a,b); 
}  
main(){ 
   Calculator(5,5,Add); 
   Calculator(5,5,Subtract); 
   Calculator(5,5,Divide); 
}

Produrrà quanto segue output -

Inside calculator 
Add result is 10 
Inside calculator 
Subtract result is 0 
Inside calculator 
Divide result is 1.0

Una libreria in un linguaggio di programmazione rappresenta una raccolta di routine (insieme di istruzioni di programmazione). Dart dispone di una serie di librerie incorporate utili per memorizzare le routine utilizzate di frequente. Una libreria Dart comprende un insieme di classi, costanti, funzioni, typedef, proprietà ed eccezioni.

Importazione di una libreria

L'importazione rende i componenti in una libreria disponibili per il codice chiamante. La parola chiave import viene utilizzata per ottenere lo stesso risultato. Un file dart può avere più istruzioni di importazione.

Gli URI della libreria Dart incorporati utilizzano lo schema dart: per fare riferimento a una libreria. Altre librerie possono utilizzare un percorso del file system o il pacchetto: schema per specificare il suo URI. Le librerie fornite da un gestore di pacchetti come lo strumento pub utilizzano il pacchetto: schema .

La sintassi per importare una libreria in Dart è fornita di seguito:

import 'URI'

Considera il seguente frammento di codice:

import 'dart:io' 
import 'package:lib1/libfile.dart'

Se desideri utilizzare solo una parte di una libreria, puoi importare selettivamente la libreria. La sintassi per lo stesso è data di seguito:

import 'package: lib1/lib1.dart' show foo, bar;  
// Import only foo and bar. 

import 'package: mylib/mylib.dart' hide foo;  
// Import all names except foo

Di seguito vengono fornite alcune librerie di uso comune:

Suor n Libreria e descrizione
1

dart:io

File, socket, HTTP e altro supporto I / O per applicazioni server. Questa libreria non funziona nelle applicazioni basate su browser. Questa libreria è importata per impostazione predefinita.

2

dart:core

Tipi, raccolte e altre funzionalità principali incorporate per ogni programma Dart. Questa libreria viene importata automaticamente.

3

dart: math

Costanti e funzioni matematiche, più un generatore di numeri casuali.

4

dart: convert

Codificatori e decodificatori per la conversione tra diverse rappresentazioni di dati, inclusi JSON e UTF-8.

5

dart: typed_data

Elenchi che gestiscono in modo efficiente dati di dimensioni fisse (ad esempio, interi a 8 byte senza segno).

Esempio: importazione e utilizzo di una libreria

L'esempio seguente importa la libreria incorporata dart: math. Lo snippet chiama il filesqrt() funzione dal mathbiblioteca. Questa funzione restituisce la radice quadrata di un numero che le è stato passato.

import 'dart:math'; 
void main() { 
   print("Square root of 36 is: ${sqrt(36)}"); 
}

Output

Square root of 36 is: 6.0

Incapsulamento nelle biblioteche

Gli script Dart possono anteporre agli identificatori un trattino basso (_) per contrassegnare i suoi componenti come privati. In poche parole, le librerie Dart possono limitare l'accesso al suo contenuto da script esterni. Questo è definito comeencapsulation. La sintassi per lo stesso è data di seguito:

Sintassi

_identifier

Esempio

In un primo momento, definire una libreria con una funzione privata.

library loggerlib;                            
void _log(msg) {
   print("Log method called in loggerlib msg:$msg");      
}

Quindi, importa la libreria

import 'test.dart' as web; 
void main() { 
   web._log("hello from webloggerlib"); 
}

Il codice precedente genererà un errore.

Unhandled exception: 
No top-level method 'web._log' declared.  
NoSuchMethodError: method not found: 'web._log' 
Receiver: top-level 
Arguments: [...] 
#0 NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:184) 
#1 main (file:///C:/Users/Administrator/WebstormProjects/untitled/Assertion.dart:6:3) 
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261) 
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

Creazione di librerie personalizzate

Dart ti consente anche di utilizzare il tuo codice come libreria. La creazione di una libreria personalizzata prevede i seguenti passaggi:

Step 1: Declaring a Library

Per dichiarare esplicitamente una libreria, utilizzare il library statement. La sintassi per dichiarare una libreria è la seguente:

library library_name  
// library contents go here

Step 2: Associating a Library

Puoi associare una libreria in due modi:

  • All'interno della stessa directory
import 'library_name'
  • Da una directory diversa
import 'dir/library_name'

Esempio: libreria personalizzata

Innanzitutto, definiamo una libreria personalizzata, calculator.dart.

library calculator_lib;  
import 'dart:math'; 

//import statement after the libaray statement  
int add(int firstNumber,int secondNumber){ 
   print("inside add method of Calculator Library ") ; 
   return firstNumber+secondNumber; 
}  
int modulus(int firstNumber,int secondNumber){ 
   print("inside modulus method of Calculator Library ") ; 
   return firstNumber%secondNumber; 
}  
int random(int no){ 
   return new Random().nextInt(no); 
}

Successivamente, importeremo la libreria -

import 'calculator.dart';  
void main() {
   var num1 = 10; 
   var num2 = 20; 
   var sum = add(num1,num2); 
   var mod = modulus(num1,num2); 
   var r = random(10);  
   
   print("$num1 + $num2 = $sum"); print("$num1 % $num2= $mod"); 
   print("random no $r"); 
}

Il programma dovrebbe produrre quanto segue output -

inside add method of Calculator Library  
inside modulus method of Calculator Library  
10 + 20 = 30 
10 % 20= 10 
random no 0

Prefisso della libreria

Se importi due librerie con identificatori in conflitto, puoi specificare un prefisso per una o entrambe le librerie. Utilizzare il'as'parola chiave per specificare il prefisso. La sintassi per lo stesso è data di seguito:

Sintassi

import 'library_uri' as prefix

Esempio

Per prima cosa, definiamo una libreria: loggerlib.dart.

library loggerlib;  
void log(msg){ 
   print("Log method called in loggerlib msg:$msg");
}

Successivamente, definiremo un'altra libreria: webloggerlib.dart.

library webloggerlib; 
void log(msg){ 
   print("Log method called in webloggerlib msg:$msg"); 
}

Infine, importeremo la libreria con un prefisso.

import 'loggerlib.dart'; 
import 'webloggerlib.dart' as web;  

// prefix avoids function name clashes 
void main(){ 
   log("hello from loggerlib"); 
   web.log("hello from webloggerlib"); 
}

Produrrà quanto segue output -

Log method called in loggerlib msg:hello from loggerlib 
Log method called in webloggerlib msg:hello from webloggerlib

Un asynchronous operation viene eseguito in un thread, separato da mainthread dell'applicazione. Quando un'applicazione chiama un metodo per eseguire un'operazione in modo asincrono, l'applicazione può continuare l'esecuzione mentre il metodo asincrono esegue la sua attività.

Esempio

Facciamo un esempio per capire questo concetto. Qui, il programma accetta l'input dell'utente utilizzando ilIO library.

import 'dart:io'; 
void main() { 
   print("Enter your name :");            
   
   // prompt for user input 
   String name = stdin.readLineSync();  
   
   // this is a synchronous method that reads user input 
   print("Hello Mr. ${name}"); 
   print("End of main"); 
}

Il readLineSync()è un metodo sincrono. Ciò significa che l'esecuzione di tutte le istruzioni che seguono ilreadLineSync() la chiamata di funzione sarà bloccata fino al readLineSync() il metodo termina l'esecuzione.

Il stdin.readLineSyncattende l'input. Si ferma sulle sue tracce e non viene più eseguito finché non riceve l'input dell'utente.

L'esempio sopra risulterà nel seguente output -

Enter your name :     
Tom                   

// reads user input  
Hello Mr. Tom 
End of main

In informatica, diciamo che qualcosa lo è synchronousquando attende che si verifichi un evento prima di continuare. Uno svantaggio di questo approccio è che se una parte del codice impiega troppo tempo per essere eseguita, l'esecuzione dei blocchi successivi, sebbene non correlati, verrà bloccata. Considera un server web che deve rispondere a più richieste di una risorsa.

Un modello di esecuzione sincrono bloccherà la richiesta di ogni altro utente fino al termine dell'elaborazione della richiesta corrente. In tal caso, come quello di un web server, ogni richiesta deve essere indipendente dalle altre. Ciò significa che il server Web non deve attendere il completamento dell'esecuzione della richiesta corrente prima di rispondere alla richiesta di altri utenti.

In poche parole, dovrebbe accettare richieste da nuovi utenti prima di completare necessariamente le richieste degli utenti precedenti. Questo è definito asincrono. La programmazione asincrona significa fondamentalmente nessun modello di programmazione in attesa o non bloccante. Ildart:async Il pacchetto facilita l'implementazione di blocchi di programmazione asincroni in uno script Dart.

Esempio

Il seguente esempio illustra meglio il funzionamento di un blocco asincrono.

Step 1 - Crea un file contact.txt file come indicato di seguito and salvalo nella cartella dei dati del progetto corrente.

1, Tom 
2, John 
3, Tim 
4, Jane

Step 2 - Scrivere un programma che leggerà il file senza bloccare altre parti dell'applicazione.

import "dart:async"; 
import "dart:io";  

void main(){ 
   File file = new File( Directory.current.path+"\\data\\contact.txt"); 
   Future<String> f = file.readAsString();  
  
   // returns a futrue, this is Async method 
   f.then((data)=>print(data));  
   
   // once file is read , call back method is invoked  
   print("End of main");  
   // this get printed first, showing fileReading is non blocking or async 
}

Il output di questo programma sarà il seguente:

End of main 
1, Tom 
2, John 
3, Tim 
4, Jan

La "fine del main" viene eseguita per prima mentre lo script continua a leggere il file. IlFuture classe, parte di dart:async, viene utilizzato per ottenere il risultato di un calcolo dopo il completamento di un'attività asincrona. QuestoFuture value viene quindi utilizzato per fare qualcosa al termine del calcolo.

Una volta completata l'operazione di lettura, il controllo dell'esecuzione viene trasferito all'interno "then()". Questo perché l'operazione di lettura può richiedere più tempo e quindi non vuole bloccare altre parti del programma.

Dart Future

La comunità Dart definisce un file Futurecome "mezzo per ottenere un valore in futuro". In poche parole,Future objectssono un meccanismo per rappresentare i valori restituiti da un'espressione la cui esecuzione verrà completata in un secondo momento. Molte delle classi integrate di Dart restituiscono un fileFuture quando viene chiamato un metodo asincrono.

Dart è un linguaggio di programmazione a thread singolo. Se un qualsiasi codice blocca il thread di esecuzione (ad esempio, aspettando un'operazione che richiede tempo o bloccando l'I / O), il programma si blocca effettivamente.

Le operazioni asincrone consentono l'esecuzione del programma senza essere bloccato. Dart utilizzaFuture objects per rappresentare operazioni asincrone.

Concurrencyè l'esecuzione di più sequenze di istruzioni contemporaneamente. Implica l'esecuzione simultanea di più attività.

Dart utilizza Isolatescome strumento per fare lavori in parallelo. Ildart:isolate pacchetto è la soluzione di Dart per prendere codice Dart a thread singolo e consentire all'applicazione di fare un uso maggiore dell'hardware disponibile.

Isolates, come suggerisce il nome, sono unità isolate di codice in esecuzione. L'unico modo per inviare dati tra di loro è passare messaggi, come il modo in cui si passano messaggi tra il client e il server. Unisolate aiuta il programma a sfruttare i microprocessori multicore fuori dagli schemi.

Esempio

Facciamo un esempio per capire meglio questo concetto.

import 'dart:isolate';  
void foo(var message){ 
   print('execution from foo ... the message is :${message}'); 
}  
void main(){ 
   Isolate.spawn(foo,'Hello!!'); 
   Isolate.spawn(foo,'Greetings!!'); 
   Isolate.spawn(foo,'Welcome!!'); 
   
   print('execution from main1'); 
   print('execution from main2'); 
   print('execution from main3'); 
}

Qui, il spawn metodo del Isolate class facilita l'esecuzione di una funzione, foo, parallelamente al resto del nostro codice. Ilspawn la funzione accetta due parametri:

  • la funzione da generare e
  • un oggetto che verrà passato alla funzione generata.

Nel caso in cui non ci siano oggetti da passare alla funzione generata, può essere passato un valore NULL.

Le due funzioni (foo and main)potrebbe non essere necessariamente eseguito nello stesso ordine ogni volta. Non vi è alcuna garanzia su quandofoo sarà in esecuzione e quando main()sarà in esecuzione. L'output sarà diverso ogni volta che esegui.

Uscita 1

execution from main1 
execution from main2 
execution from main3 
execution from foo ... the message is :Hello!!

Uscita 2

execution from main1 
execution from main2 
execution from main3 
execution from foo ... the message is :Welcome!! 
execution from foo ... the message is :Hello!! 
execution from foo ... the message is :Greetings!!

Dagli output, possiamo concludere che il codice Dart può generare un nuovo file isolate dall'esecuzione di codice come il modo in cui il codice Java o C # può avviare un nuovo thread.

Isolates differiscono dai thread in quanto un file isolateha una sua memoria. Non c'è modo di condividere una variabile traisolates—L'unico modo per comunicare tra di loro isolates avviene tramite passaggio di messaggi.

Note - L'output di cui sopra sarà diverso per diverse configurazioni di hardware e sistema operativo.

Isolare il futuro

L'esecuzione di un lavoro computazionale complesso in modo asincrono è importante per garantire la reattività delle applicazioni. Dart Future è un meccanismo per recuperare il valore di un'attività asincrona dopo che è stata completata, mentre Dart Isolates sono uno strumento per astrarre il parallelismo e implementarlo su una base pratica di alto livello.

Lo unit test implica il test di ogni singola unità di un'applicazione. Aiuta lo sviluppatore a testare piccole funzionalità senza eseguire l'intera complessa applicazione.

Il Dart external library denominato "test" fornisce un modo standard di scrivere ed eseguire unit test.

Il test dell'unità Dart prevede i seguenti passaggi:

Step 1: Installing the "test" package

Per installare pacchetti di terze parti nel progetto corrente, sarà necessario il file pubspec.yamlfile. Installaretest packages, prima inserisci la seguente voce nel file pubspec.yaml file -

dependencies: 
test:

Dopo aver effettuato l'immissione, fare clic con il pulsante destro del mouse su pubspec.yamlfile e ottenere le dipendenze. Installerà il"test"pacchetto. Di seguito è riportato uno screenshot per lo stesso inWebStorm Editor.

I pacchetti possono essere installati da command linepure. Digita quanto segue nel terminale:

pub get

Step 2: Importing the "test" package

import "package:test/test.dart";

Step 3 Writing Tests

I test vengono specificati utilizzando la funzione di primo livello test(), mentre test assertions sono realizzati utilizzando il expect()funzione. Per utilizzare questi metodi, dovrebbero essere installati come filepub dipendenza.

Sintassi

test("Description of the test ", () {  
   expect(actualValue , matchingValue) 
});

Il group()può essere utilizzata per raggruppare i test. La descrizione di ogni gruppo viene aggiunta all'inizio delle descrizioni del suo test.

Sintassi

group("some_Group_Name", () { 
   test("test_name_1", () { 
      expect(actual, equals(exptected)); 
   });  
   test("test_name_2", () { 
      expect(actual, equals(expected)); 
   }); 
})

Esempio 1: un test di superamento

L'esempio seguente definisce un metodo Add(). Questo metodo accetta due valori interi e restituisce un numero intero che rappresenta ilsum. Per provare questoadd() metodo -

Step 1 - Importa il file test pacchetto come indicato di seguito.

Step 2 - Definisci il test utilizzando il file test()funzione. Qui, iltest() utilizza la funzione expect() funzione per imporre un'asserzione.

import 'package:test/test.dart';      
// Import the test package 

int Add(int x,int y)                  
// Function to be tested { 
   return x+y; 
}  
void main() { 
   // Define the test 
   test("test to check add method",(){  
      // Arrange 
      var expected = 30; 
      
      // Act 
      var actual = Add(10,20); 
      
      // Asset 
      expect(actual,expected); 
   }); 
}

Dovrebbe produrre quanto segue output -

00:00 +0: test to check add method 
00:00 +1: All tests passed!

Esempio 2: un test fallito

Il subtract()il metodo definito di seguito presenta un errore logico. Il seguentetest verifica lo stesso.

import 'package:test/test.dart'; 
int Add(int x,int y){ 
   return x+y; 
}
int Sub(int x,int y){ 
   return x-y-1; 
}  
void main(){ 
   test('test to check sub',(){ 
      var expected = 10;   
      // Arrange 
      
      var actual = Sub(30,20);  
      // Act 
      
      expect(actual,expected);  
      // Assert 
   }); 
   test("test to check add method",(){ 
      var expected = 30;   
      // Arrange 
      
      var actual = Add(10,20);  
      // Act 
      
      expect(actual,expected);  
      // Asset 
   }); 
}

Output - Il test case per la funzione add() passa ma il test per subtract() fallisce come mostrato di seguito.

00:00 +0: test to check sub 
00:00 +0 -1: test to check sub 
Expected: <10> 
Actual: <9> 
package:test  expect 
bin\Test123.dart 18:5  main.<fn> 
   
00:00 +0 -1: test to check add method 
00:00 +1 -1: Some tests failed.  
Unhandled exception: 
Dummy exception to set exit code. 
#0  _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:938) 
#1  _microtaskLoop (dart:async/schedule_microtask.dart:41)
#2  _startMicrotaskLoop (dart:async/schedule_microtask.dart:50) 
#3  _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394) 
#4  _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414) 
#5  _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

Raggruppamento di casi di test

Puoi raggruppare i file test casesin modo che aggiunga più significato al codice di prova. Se ne hai moltitest cases questo aiuta a scrivere codice molto più pulito.

Nel codice fornito, stiamo scrivendo un test case per split() funzione e il trimfunzione. Quindi, raggruppiamo logicamente questi casi di test e li chiamiamoString.

Esempio

import "package:test/test.dart"; 
void main() { 
   group("String", () { 
      test("test on split() method of string class", () { 
         var string = "foo,bar,baz"; 
         expect(string.split(","), equals(["foo", "bar", "baz"])); 
      }); 
      test("test on trim() method of string class", () { 
         var string = "  foo "; 
         expect(string.trim(), equals("foo")); 
      }); 
   }); 
}

Output - L'output aggiungerà il nome del gruppo per ogni caso di test come indicato di seguito -

00:00 +0: String test on split() method of string class 
00:00 +1: String test on trim() method of string class 
00:00 +2: All tests passed

Ogni pagina web risiede all'interno di una finestra del browser che può essere considerata come un oggetto.

UN Document objectrappresenta il documento HTML visualizzato in quella finestra. L'oggetto Document ha varie proprietà che fanno riferimento ad altri oggetti che consentono l'accesso e la modifica del contenuto del documento.

Il modo in cui si accede al contenuto di un documento e lo si modifica è chiamato Document Object Model, o DOM. Gli oggetti sono organizzati in una gerarchia. Questa struttura gerarchica si applica all'organizzazione degli oggetti in un documento Web.

  • Window- In cima alla gerarchia. È l'elemento più esterno della gerarchia degli oggetti.

  • Document- Ogni documento HTML che viene caricato in una finestra diventa un oggetto documento. Il documento contiene il contenuto della pagina.

  • Elements- rappresentare il contenuto su una pagina web. Gli esempi includono le caselle di testo, il titolo della pagina ecc.

  • Nodes - sono spesso elementi, ma possono anche essere attributi, testo, commenti e altri tipi di DOM.

Ecco una semplice gerarchia di alcuni importanti oggetti DOM:

Dart fornisce il dart:htmllibreria per manipolare oggetti ed elementi nel DOM. Le applicazioni basate su console non possono utilizzare l'estensionedart:htmlbiblioteca. Per utilizzare la libreria HTML nelle applicazioni web, importadart:html -

import 'dart:html';

Andando avanti, ne discuteremo alcuni DOM Operations nella sezione successiva.

Trovare elementi DOM

Il dart:html library fornisce il querySelector funzione per cercare elementi nel DOM.

Element querySelector(String selectors);

Il querySelector() restituisce il primo elemento che corrisponde al gruppo di selettori specificato. "selectors dovrebbe essere una stringa utilizzando la sintassi del selettore CSS come indicato di seguito

var element1 = document.querySelector('.className'); 
var element2 = document.querySelector('#id');

Esempio: manipolazione di DOM

Segui i passaggi indicati di seguito, nell'IDE Webstorm -

Step 1 - File NewProject → Nella posizione, fornire il nome del progetto come DemoWebApp.

Step 1 - Nella sezione "Genera contenuto di esempio", seleziona SimpleWebApplication.

Creerà un progetto di esempio, DemoWebApp. C'è unpubspec.yaml file contenente le dipendenze che devono essere scaricate.

name: 'DemoWebApp' 
version: 0.0.1 
description: An absolute bare-bones web app. 

#author: Your Name <[email protected]> 
#homepage: https://www.example.com  
environment:   
   sdk: '>=1.0.0 <2.0.0'  
dependencies:   
   browser: '>=0.10.0 <0.11.0'   dart_to_js_script_rewriter: '^1.0.1'  
transformers: 
- dart_to_js_script_rewriter

Se sei connesso al Web, questi verranno scaricati automaticamente, altrimenti puoi fare clic con il pulsante destro del mouse sul file pubspec.yaml e ottieni le dipendenze.

Nella cartella web troverai tre file: Index.html, main.dart, e style.css

Index.html

<!DOCTYPE html>   
<html> 
   <head>     
      <meta charset = "utf-8">     
      <meta http-equiv = "X-UA-Compatible" content = "IE = edge">     
      <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
      <meta name = "scaffolded-by" content = "https://github.com/google/stagehand">
      <title>DemoWebApp</title>     
      <link rel = "stylesheet" href = "styles.css">     
      <script defer src = "main.dart" type = "application/dart"></script>
      <script defer src = "packages/browser/dart.js"></script> 
   </head>
   
   <body>   
      <h1>
         <div id = "output"></div> 
      </h1>  
   </body> 
</html>

Main.dart

import 'dart:html';  
void main() {   
   querySelector('#output').text = 'Your Dart web dom app is running!!!.'; 
}

Corri il index.htmlfile; vedrai il seguente output sullo schermo.

Gestione degli eventi

Il dart:html library fornisce il onClickevento per elementi DOM. La sintassi mostra come un elemento può gestire un flusso di eventi di clic.

querySelector('#Id').onClick.listen(eventHanlderFunction);

Il querySelector() funzione restituisce l'elemento dal DOM dato e onClick.listen() prenderà un eventHandlermetodo che verrà richiamato quando viene generato un evento clic. La sintassi dieventHandler è dato di seguito -

void eventHanlderFunction (MouseEvent event){ }

Facciamo ora un esempio per comprendere il concetto di gestione degli eventi in Dart.

TestEvent.html

<!DOCTYPE html> 
<html> 
   <head> 
      <meta charset = "utf-8"> 
      <meta http-equiv = "X-UA-Compatible" content = "IE = edge"> 
      <meta name = "viewport" content = "width = device-width, initial-scale = 1.0"> 
      <meta name = "scaffolded-by" content ="https://github.com/google/stagehand"> 
      <title>DemoWebApp</title> 
      <link rel = "stylesheet" href = "styles.css"> 
      <script defer src = "TestEvent.dart" type="application/dart"></script> 
      <script defer src = "packages/browser/dart.js"></script> 
   </head> 
   
   <body> 
      <div id = "output"></div> 
      <h1> 
         <div> 
            Enter you name : <input type = "text" id = "txtName"> 
            <input type = "button" id = "btnWish" value="Wish"> 
         </div> 
      </h1> 
      <h2 id = "display"></h2> 
   </body>
   
</html>

TestEvent.dart

import 'dart:html'; 
void main() { 
   querySelector('#btnWish').onClick.listen(wishHandler); 
}  
void wishHandler(MouseEvent event){ 
   String name = (querySelector('#txtName')  as InputElement).value; 
   querySelector('#display').text = 'Hello Mr.'+ name; 
}

Produzione