Ghidul începătorului de a introduce coerciția Ce este coerciția?

În această serie, luăm o privire începătorului la limbi tipizate dinamic (sau slab tastate) și modul în care lipsa lor de tastare puternică poate avea un impact atât pozitiv cât și negativ asupra programării.

După cum sa menționat în primul post, această serie este orientată în mod special spre începători sau spre cei care nu au o experiență foarte bună cu limbi slabe. Asta inseamna ca daca ati programat atat in limbile puternic tastate cat si / sau slab tastate si sunteti familiarizati cu coercitia de tip si cu capcanele care pot aparea atunci cand efectuati anumite operatii, atunci aceasta serie poate sa nu aiba prea mare interes pentru dumneavoastra.

Pe de altă parte, dacă sunteți cineva care începe să scrie codul sau sunteți cineva care intră într-un limbaj dinamic din altă limbă, atunci această serie este orientată în mod special către dvs. În cele din urmă, obiectivul este de a defini coerciția de tip, de a arăta cum funcționează, și apoi de a examina capcanele.

Coerciția definită

Potrivit Wikipedia, constrângerea este definită după cum urmează:

În domeniul informaticii, tipul conversiei, tipcasting-ul și coerciția sunt modalități diferite de a schimba implicit sau explicit o entitate dintr-un tip de date într-un altul.

Sau, poate într-un mod mai simplu, puteți defini acest lucru ca modul în care luați un tip de date și îl convertiți în altul. Lucrul este că există o linie perfectă între conversie și constrângere. 

Ca regulă generală, am tendința să mă gândesc constrângere cum funcționează un interpret sau un compilator pentru a determina ce fel de comparație se face, în timp ce conversie este o schimbare explicită a tipului pe care noi, ca programator, o scriem în codul nostru.

Să ne uităm la acest lucru în detaliu.

Tip de conversie

Să spunem, de exemplu, că aveți un șir denumit exemplu și valoarea lui este '5'. În limbile statice tipărite, puteți tipări acest lucru apucați valoarea șirului și îl convertiți la un int printr-o serie de metode diferite.

Să presupunem că avem unul Întreg obiect cu a parseInt metodă. Metoda acceptă un șir și returnează valoarea șirului în tipul de date întreg. Codul pentru acest lucru poate arata cam asa:

string exemplu = '5'; Integer myInt = Integer nou (); int intExample = intentul meu (exemplu); / * intExample are acum valoarea 5 (nu '5') * și exemplul se referă încă la șirul '5' * /

Desigur, sintaxa va varia de la limbă la limbă și acolo sunteți alte moduri de a merge despre distribuirea unei valori, dar aceasta vă oferă o idee despre cum să convertiți în mod explicit un tip în altul.

Un alt mod de a face acest lucru este de a utiliza un operator de turnare de tip. Deși implementarea operațiunii variază de la limbă la limbă, majoritatea programatorilor care au lucrat cu limbi în stil C o vor recunoaște probabil ca ceva asemănător cu acesta:

int myInt = (int) exemplu;

În general vorbind, turnarea de tip se face de obicei prin plasarea tipului în care doriți să convertiți variabila în paranteze înaintea variabilei în sine. În exemplul de mai sus, Myint va conține acum 5, Decat '5' și exemplu va rămâne în continuare '5'.

După cum sa spus, acest lucru este în mod normal făcut în contextul limbilor compilate

Tip de constrângere

Aceasta lasă în continuare problema modului în care constrângerea de tip diferă de conversia de tip. Deși coerciție poate sa se întâmplă în limbi compilate, este mult mai probabil că veți vedea că se întâmplă în limbi interpretate sau în limbi dinamice tipărite.

Mai mult decât atât, sunteți mai mult decât probabil să vedeți coerciția de tip care se întâmplă ori de câte ori se face o comparație între obiecte de diferite tipuri sau atunci când se efectuează o operație sau o evaluare cu variabile care au diferite tipuri.

Ca un exemplu simplu, să spunem că în JavaScript avem două variabile - sName, iAge - Unde sName se referă la numele persoanei și la iAge se referă la vârsta unei persoane. Variabilele, în scopuri de exemplu, utilizează notația ungară pentru a desemna pur și simplu faptul că unul stochează un șir și unul stochează un întreg.

Rețineți că aceasta este nu un argument pentru sau împotriva notării maghiare - acesta este un subiect pentru alt post. Este folosit aici pentru a clarifica ce tip de valoare este stocată fiecare variabilă, astfel încât să fie mai ușor să urmați codul.

Așa că vom merge mai departe și vom defini variabilele și valorile noastre:

var sName = 'John Doe'; var iAge = 32;

Acum, putem examina câteva exemple de funcționare a tipului de constrângere în contextul unui limbaj interpretat. Două exemple de funcționare a tipului de constrângere sunt următoarele:

  1. Comparând un număr cu un boolean
  2. Concatenarea unui șir și a unui număr

Să aruncăm o privire la un exemplu de fiecare:

/ ** * Compararea unui număr cu un boolean * va avea ca rezultat valoarea booleană * a lui 'false'. * / var rezultat = iAge == adevărat; / ** * Corzile și numerele de concatenare vor forța numărul la un șir. * * "John Doe are 32 de ani." * / var bio = sName + 'este' + iAge + 'de ani.';

Aceste exemple sunt relativ simple. Primul are sens deoarece nu există nici o modalitate prin care un număr să poată fi comparat cu o valoare booleană. 

În cel de-al doilea exemplu, observați că luăm un șir, concatenând-l cu un alt set de șiruri de caractere și utilizând și numărul din operația de concatenare. În acest caz, numărul este convertit într-un șir și apoi este concatenat împreună cu restul cuvintelor.

Aceasta este coerciția de tip: atunci când luați o variabilă de un tip și convertiți valoarea acesteia într-un alt tip atunci când efectuați o operație sau o evaluare. 

Chestia este că ambele exemple sunt foarte simpliste. Să aruncăm o privire asupra câtorva mai multe pentru a demonstra modul în care coerciția funcționează, cel puțin în JavaScript, atunci când efectuează operații de concatenare:

var one, two, rezultat; // una și două se referă la valorile șirului de '1' și '2' unul = '1'; două = '2'; // rezultatul va conține șirul "12"; rezultat = 1 + 2; // redefiniți două pentru a egala numărul '2' doi = 2; // concatenarea unui șir și a unui număr are ca rezultat un șir // rezultatul va conține '12'; rezultat = 1 + 2; // redefinește unul ca număr unu = 1; // apoi concatenați (sau suma) cele două valori // rezultatul va fi 3 rezultat = unul + două;

Există două lucruri importante:

  1. + operatorul este supraîncărcat. Asta inseamna ca atunci cand lucreaza cu siruri de caractere, le conecteaza impreuna, dar cand lucreaza cu numere, le adauga impreuna.
  2. Un tip este întotdeauna forțat în altul și în mod normal există o ierarhie a modului în care apare. Deși fiecare limbă este diferită, rețineți că în al doilea exemplu când concatenăm un șir și un număr, rezultatul este un șir. Acest lucru se datorează faptului că numărul este constrânsă într-un șir.

Pentru a face exemplul cu un pas mai departe, să adăugăm încă o variabilă, un set de operații prioritare și apoi să examinăm rezultatul:

var one, two, tree, rezultat; unul = '1'; doi = 2; trei = 3; // rezultatul este '123' rezultat = 1 + 2 + 3; // rezultatul este '15' rezultat = unul + (doi + trei);

Observați în cel de-al doilea exemplu, Două și Trei sunteți adăugat împreună pentru că sunt ambele numere și apoi rezultatul este concatenate cu unu pentru că este un șir.

Anterior, am menționat că există un caz special pentru numere și valori booleene, cel puțin în JavaScript. Și din moment ce aceasta este limba pe care am folosit-o pentru a examina coerciția de tip și din moment ce aceasta este o limbă care este frecvent folosită în dezvoltarea web modernă, să aruncăm o privire.

În cazul JavaScript, rețineți că 1 este considerată a fi o valoare "tristă" și 0 este preocupat de a fi o valoare "falsă". Aceste cuvinte sunt alese ca atare, deoarece valorile pot servi drept numere, dar vor fi de asemenea evaluate Adevărat sau fals atunci când efectuați o comparație.

Să aruncăm o privire la câteva exemple de bază:

var bTrue, bFalse, iZero, iOne, rezultat; bTrue = adevărat; bFalse = false; iZero = 0; iOne = 1; // rezultă valoarea valorii booleene a rezultatului false = bTrue == iZero; // rezultat deține valoarea booleană a rezultatului adevărat = bTrue == iOne; // rezultat deține valoarea booleană a rezultatului false = bFalse == iOne; // rezultat deține valoarea booleană a rezultatului adevărat = bFalse == iZero;

Observați că în exemplele de mai sus, valorile numerice sunt constrânsă în valori întregi prin natura comparației făcute.

Dar ce se întâmplă dacă vom compara o valoare booleană Adevărat sau fals la o valoare de șir de unu sau zero?

var bTrue, bFalse, sTrue, sFalse, rezultat; bTrue = adevărat; bFalse = false; sTrue = '1'; sFalse = '0'; // rezultatul are rezultatul adevărat = bTrue == sTrue; // rezultatul are un rezultat fals = bTrue == sFalse; // rezultatul este fals; rezultat = bFalse == sTrue; // rezultatul are rezultatul real = bFalse == sFalse;

În acest moment, lucrurile pot începe să devină foarte confuze, deoarece comparăm o valoare de șir a unui număr care este 1 la o valoare booleană Adevărat și obținem un rezultat boolean, iar booleanul este Adevărat.

Are sens? Vom analiza acest lucru într-un mod mai detaliat în articolul următor, dar am vrut să continuăm și să prezentăm mai întâi elementele de bază ale acestuia.

Urmeaza…

Acest lucru se întâmplă atunci când limbajele tastate dinamic pot începe să provoace dureri de cap pentru dezvoltatori. Din fericire, există modalități prin care putem scrie coduri mai stricte decât cele de mai sus și care oferă rezultate precise.

În plus, unele limbi introduse dinamic conțin, de asemenea, valori pentru nedefinit si pentru nul. Acestea mențin, de asemenea, valori "trist" și "false" care, la rândul lor, afectează modul în care ne confruntăm cu comparațiile.

În ultimul articol din serie, vom examina cum valorile cum ar fi nedefinit și nul să se compare cu alte valori, precum și cu altele și să aruncăm o privire asupra unor strategii pe care le putem implementa, ceea ce va face ca codul nostru să fie mai rezistent față de coerciția de tip incorect și care îl face mai ușor de citit.

Dacă aceasta este prima dvs. incursiune în limbi dinamice tipărite sau tip de coerciție și aveți întrebări, comentarii sau feedback, vă rugăm să nu ezitați să lăsați un comentariu în feed-ul de mai jos!

Cod