Nybörjarens guide till typtyngd Vad är tvång?

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.

Tvångsdefinition

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.

Typkonvertering

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

Typ tvång

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:

  1. Jämförelse av ett tal till en booleska
  2. Sammanfoga en sträng och ett tal

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:

  1. De + 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.
  2. En typ är alltid tvingad till en annan och det finns normalt en hierarki för hur det uppstår. Även om varje språk är annorlunda, notera att i det andra exemplet när vi sammanfogar en sträng och ett tal är resultatet en sträng. Detta beror på att numret är tvingad in i en sträng.

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.

Kommer härnäst…

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!