I den här serien tar vi en nybörjarens titt på dynamiskt typade språk (eller svagt typade) och hur deras brist på starkt skrivning kan både positivt och negativt påverka vår programmering.
Som nämnts i första inlägget är denna serie speciellt inriktad på nybörjare eller mot dem som inte har mycket erfarenhet av svagt typade språk. Det vill säga att om du har programmerat på både starkt skrivna och / eller svagt typade språk och känner till typtyngd och fallgropar som kan uppstå vid vissa operationer, kanske den här serien kanske inte är av stor intresse för dig.
Å andra sidan, om du är någon som just har börjat skriva kod eller du är någon som kommer in i ett dynamiskt skrivet språk från ett annat språk, så är den här serien inriktad mot dig. I slutändan är målet att definiera typ tvång, visa hur det fungerar och undersöka sedan fallgroparna.
Enligt Wikipedia definieras tvång enligt följande:
I datavetenskap är typkonvertering, typprovning och tvång olika sätt att implicit eller explicit ändra en enhet av en datatyp till en annan.
Eller kanske på ett enklare sätt kan du definiera detta som hur du tar en datatyp och konverterar den till en annan. Saken är, det finns en bra linje mellan konvertering och tvång.
Som en allmän tumregel tenderar jag att tänka på tvång som hur en tolk eller kompilator arbetar för att bestämma vilken typ av jämförelse som görs, medan omvandling är en explicit förändring av typ som vi som programmerare skriver i vår kod.
Låt oss se mer på det här.
Låt oss exempelvis säga att du har en sträng som heter exempel
och dess värde är '5'
. På statiskt typade språk kan du skriva cast det här ta tag i värdet på strängen och konvertera det till en int
genom ett antal olika metoder.
Antag att vi har en Heltal
objekt med a parseInt
metod. Metoden accepterar en sträng och returnerar strängens värde i heltaldatatypen. Koden för att göra det kan se ut så här:
strängexempel = '5'; Heltal myInt = nytt heltal (); int intExample = myInt.parseInt (exempel); / * intExample har nu värdet 5 (inte '5') * och exempel hänvisar fortfarande till strängen '5' * /
Självklart kommer syntaxen att variera från språk till språk och där är Andra sätt att gå om att casta ett värde, men det här ger dig en uppfattning om hur man uttryckligen omvandlar en typ till en annan.
Ett annat sätt att gå om att göra detta är att använda en typgjutningsoperatör. Även om genomförandet av operationen varierar från språk till språk, kommer de flesta programmerare som har arbetat med C-stil språk säkert att känna igen det som något liknande det här:
int myInt = (int) exempel;
Generellt sett görs typgjutning vanligen genom att placera typen som du vill konvertera variabeln inom parentes före själva variabeln. I exemplet ovan, myInt
kommer nu att innehålla 5
, hellre än '5'
och exempel
kommer fortfarande att hålla '5'
.
Som sagt är det något som normalt görs inom ramen för sammanställda språk
Detta lämnar fortfarande frågan om hur typen tvång skiljer sig från typkonvertering. Trots tvång kan händer inom kompilerade språk, är det mer troligt att du kommer att se det hända inom tolkade språk eller på dynamiskt typade språk.
Dessutom är det mer än troligt att du ser att tvångstvång inträffar när en jämförelse görs mellan objekt av olika slag eller när en operation eller utvärdering görs med variabler som har olika typer.
Som ett enkelt exempel, låt oss säga att i JavaScript har vi två variabler - sNAME
, iAge
- var sNAME
avser en persons namn och iAge
avser en persons ålder. Variablerna, för exempel, använder ungerska notering för att bara ange att man lagrar en sträng och man lagrar ett heltal.
Observera att detta är inte ett argument för eller mot ungerska notering - det är ett ämne för ett annat inlägg. Den används här för att klargöra vilken typ av värde varje variabel lagras så att det är lättare att följa koden.
Så vi ska gå vidare och definiera våra variabler och deras värden:
var sName = 'John Doe'; var iAge = 32;
Nu kan vi titta på några exempel på hur typen tvång fungerar inom ramen för ett tolkat språk. Två exempel på hur typen av tvång fungerar är som följer:
Låt oss ta en titt på ett exempel på var och en:
/ ** * Att jämföra ett tal till en boolesk * kommer att resultera i det booleska värdet * av "false". * / var resultat = iAge == true; / ** * Sammanställnings strängar och tal kommer att * tvinga numret till en sträng. * * "John Doe är 32 år gammal." * / var bio = sName + 'är' + iAge + 'år gammal.';
Dessa exempel är relativt enkla. Den första är meningsfull eftersom det inte finns något sätt att ett tal kan jämföras med ett booleskt värde.
I det andra exemplet märker vi att vi tar en sträng, sammanfogar den med en annan uppsättning strängar och använder även numret i sammanbindningsoperationen. I detta fall omvandlas numret till en sträng och sammanfogas sedan med resten av orden.
Detta är typtyngd: När du tar en variabel av en typ och konverterar den till ett annat slag när du utför en operation eller utvärdering.
Saken är, båda dessa exempel är mycket enkla. Låt oss titta på några fler för att visa hur tvång fungerar, åtminstone i JavaScript, när du utför sammanbindningsoperationer:
var en, två, resultatet; // en och två hänvisar till strängvärdena på '1' och '2' one = '1'; två = '2'; // Resultatet kommer att innehålla strängen '12'; resultat = en + två; // omdefiniera två till lika med antalet '2' two = 2; // sammanlänka en sträng och ett tal resulterar i en sträng // resultatet innehåller "12"; resultat = en + två; // omdefiniera en som nummer ett = 1; // då concatenate (eller summa) de två värdena // resultatet blir 3 resultat = en + två;
Det finns två viktiga saker att notera:
+
Operatören är överbelastad. Det betyder att när det arbetar med strängar, sammanfogar de dem tillsammans, men när det arbetar med siffror lägger det till dem tillsammans.För att ta exemplet ett steg längre, lägger vi till ytterligare en variabel, en prioriterad uppsättning operationer och undersöker sedan resultatet:
var ett, två, träd, resultat; en = '1'; två = 2; tre = 3; // resultatet är '123' resultat = en + två + tre; // resultatet är '15' resultat = en + (två + tre);
Observera i det andra exemplet, två
och tre
är Lagt till tillsammans eftersom de båda är siffror och då är resultatet konkatenerade med ett
eftersom det är en sträng.
Tidigare nämnde vi att det finns ett speciellt fall för tal och booleska värden, åtminstone i JavaScript. Och eftersom det är språket som vi har använt för att undersöka typtyngd och eftersom det är ett språk som ofta används i modern webbutveckling, låt oss ta en titt.
När det gäller JavaScript, notera att 1
anses vara ett "sant" värde och 0
är orolig för att vara ett "falsey" -värde. Dessa ord väljs som sådana eftersom värdena kan tjäna som nummer, men kommer också att utvärderas till Sann
eller falsk
när man utför en jämförelse.
Låt oss ta en titt på några grundläggande exempel:
var bTrue, bFalse, iZero, iOne, resultat; bTrue = true; bFalse = false; iZero = 0; iOne = 1; // Resultat håller det booleska värdet av falskt resultat = bTrue == iZero; // resultatet håller det booleska värdet av det sanna resultatet = bTrue == iOne; // Resultat håller det booleska värdet av falskt resultat = bFalse == iOne; // resultatet håller det booleska värdet av sant resultat = bFalse == iZero;
Observera att numreringsvärdena i exemplen ovan är tvingad i heltalsvärden av naturen av den jämförelse som görs.
Men vad händer om vi ska jämföra ett booleskt värde av Sann
eller falsk
till ett strängvärde av ett
eller noll-
?
var bTrue, bFalse, sTrue, sFalse, resultat; bTrue = true; bFalse = false; sTrue = '1'; sFalse = '0'; // resultatet håller sant resultat = bTrue == sTrue; // Resultat håller falskt resultat = bTrue == sFalse; // Resultat håller false; result = bFalse == sTrue; // Resultatet håller sant resultat = bFalse == sFalse;
På den här tiden kan saker börja bli förvirrande eftersom vi jämför ett strängvärde för ett nummer som är 1
till ett booleskt värde av Sann
och vi får ett booleskt resultat, och den booleska är Sann
.
Vettigt? Vi tar en titt på det här i lite mer detalj i nästa artikel, men jag ville gå vidare och presentera grunderna först.
Det här är när dynamiskt skrivna språk kan börja orsaka huvudvärk för utvecklare. Lyckligtvis finns det sätt på vilka vi kan skriva kod som är strängare än vad vi har ovan och som ger noggranna resultat.
Dessutom innehåller vissa dynamiskt typade språk också värden för odefinierad
och för null
. Dessa upprätthåller också "truthy" och "falsey" -värden som i sin tur påverkar hur vi hanterar jämförelser.
I den sista artikeln i serien ska vi titta på hur värden som odefinierad
och null
jämföra med andra värderingar såväl som med varandra och ta en titt på några strategier som vi kan genomföra som gör vår kod mer motståndskraftig mot felaktig typtyngd och det gör det lättare att läsa.
Om detta är din första fördjupning till dynamiskt skrivna språk eller typ av tvång och du har frågor, kommentarer eller feedback, tveka inte att lämna en kommentar i foderet nedan!