Forstå variabler, Arrays, Loops og Null: De Post

Understanding Variabler, Arrays, Loops, og Null: The Post-it lapp analogi
to
Del
11

Del
Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Hva Var faktisk gjør, og hvorfor ikke sette myObject = null faktisk fjerne objektet? Disse spørsmålene knytte til en grunnleggende begrep i koding, relevant hvorvidt språket av valget er AS3, Javascript, eller C #, og kan forstås ved hjelp av noen vanlige elementer fra saker skapet.




Hva er en variabel?

La oss starte med det grunnleggende. Tenk deg at du ønsker å lagre en alder av din venn Bill:
Var ageOfBill. Number = 24;

(Jeg kommer til å bruke AS3 for disse eksempel, men de grunnleggende konseptene er de samme i Javascript og C #

I Javascript, er syntaksen nesten det samme, men vi spesifiserer ikke at alder er et tall:
Var ageOfBill = 24;

I C # vi ikke bruke VAR søkeord, men vi spesifiserer hvilken type variabelen:
kort ageOfBill = 24;

Ikke annerledes nok til å være forvirrende, håper jeg)

Så hva er det som skjer her.? Tenk på det på denne måten:

var (eller kort, i C #) betyr "få en ny Post-it lapp"

ageOfBill betyr, "skriver ageOfBill øverst. i pennen ".

= 24 betyr," skriver 24 på lappen, med blyant ".

Hva om senere vi innser at Bills faktisk yngre enn vi trodde?
Var ageOfBill = 24; //... senere ... ageOfBill = 20;.

Dette betyr bare vi finner vår ageOfBill notat, slette 24, og skriv 20 på den i stedet

kunne
write Var igjen:
Var ageOfBill: Number = 24; //... senere ... Var ageOfBill: Number = 20;

... men dette er ikke god kode, fordi Var sier: "få en ny Post-it lapp". Hvis du gjør dette, vil kompilatoren vanligvis finne ut hva du mener - det vil si at du ønsker å endre hva som er skrevet på eksisterende ageOfBill Post-it lapp i stedet for faktisk å få en ny en - men det vil trolig klage
Advarsel:. # 3596:.. Duplicate variabel definisjon

Det avhenger av språket og på kodemiljø

Så kan vi spørre kompilatoren for å få en frisk Post-it lapp og skrive en merkelapp på det i pennen, uten å skrive noe på det med blyant? Kanskje vi kunne gjøre dette for Bills venn Marty, hvis alder vi vet ikke:
Var ageOfMarty: Number;

Egentlig (i AS3, minst) dette vil få en frisk Post-it lapp, skrive ageOfMarty tvers toppen, i pennen ... og deretter skrive et standard initial verdi på 0 på det med blyant:

Så, med andre ord, vi kan ikke ha en Post-it lapp som dette uten at det tar noen verdi

Ok - hva om hvis vi ønsker å lagre en alder av Bill beste venn Ted, som vi vet er på samme alder
Var ageOfTed:.? Number = ageOfBill;

Hva skjer her er , ser datamaskinen på ageOfBill Post-it, deretter kopierer nummer skrevet på den med blyant til en frisk Post-it, som den skriver ageOfTed øverst i pennen.

Dette er bare en kopi, skjønt; hvis vi da endre verdien av ageOfBill det vil ikke påvirke ageOfTed:
ageOfBill = 21;

So! Det er alt ganske grei, og kanskje til og med intuitive. Nå la oss snakke om den første felles smerte punktet. Arrays



Hva er en Array

Tenk på en matrise som en ringperm

(jeg skulle?. å si en rolodex ...

... men jeg innså at jeg hadde aldri sett en i det virkelige liv.)

Hvert ark inne i bindemiddel er som en av de Post-it notater, unntatt uten pennen skrevne etiketten øverst. I stedet henviser vi til hvert ark ved navn bindemiddel og sidetallet av arket.

La oss anta at vi har fått en rekke alle våre venner, i ingen spesiell rekkefølge. Hvem er på første side (side # 0)
spore (venner [0]);

(trace () bare skriver linjen til avlusningsinformasjon, i Javascript, kan du bruke console.log () og i C # du kan bruke Console.WriteLine () for samme formål)

Det er
Bill

Så nå, hva betyr følgende linje gjør
Var firstFriend:.!? String = venner [0];.

Det blir en frisk Post-it lapp (på grunn av Var søkeord), skriver firstFriend øverst i pennen, deretter kopier det som står skrevet på første side av bindemiddelet på at notatet i blyant

(Husk, String betyr bare en del av teksten.)

Vi kan overskrive hva som er skrevet på en side av bindemiddelet, akkurat som med Post-it-lapper:
venner [0 ] = "Kyle";

... og selvfølgelig dette ikke påvirker firstFriend Post-it

Bindemiddelet er en passende analogi, fordi - akkurat som med en rekke - du ta ta. sider ut, legge til nye, og omorganisere dem. Men husk, enkeltsider opptre akkurat som Post-it-lapper, bortsett fra at de ikke har egne penn etiketter, bare sidetall.

Likevel ganske grei, håper jeg. Så her er et interessant spørsmål: hva skjer når du gjør følgende
Var listOfNames: Array = venner;

Uh ...



Du kan ikke skrive det på en Post- det

Jeg har jukset litt her, fordi jeg snakket en haug om arrays uten noen gang å forklare hvordan vi skaper en i første omgang. . Så la oss takle det nå

Tenk deg at du skriver:
Var venner: Array = ["Bill", "Marty", "Ted"];

... Hva skjer

Vel, som vanlig, betyr Var venner vi får en frisk Post-it lapp og skrive venner over toppen, i penn:?

Men hva gjør vi skriver om den i blyant

Det er et lurespørsmål: vi ikke skrive noe

Se, Array betyr, "få en ny ringperm".. Og ["Bill", "Marty", "Ted"] betyr "satt tre sider i ringperm, med disse navnene på det":
Du kan ikke se "Marty" og "Ted" sider , men de er helt der.

Og så? Det er enkelt! Vi holder venner Post-it lapp til dekning av binde:

Nå, når vi skriver:
trace (venner [0]);

... vi vet at vi må finne Post-it merket venner, og deretter se på hva som er skrevet på første side (side # 0) av binde at det er fast til.

Det er faktisk veldig få typer av variabel der verdien blir skrevet ut en Post-it lapp med blyant. I AS3, de bare slike typer (kalt "primitive") er:

Antall

String

int

uint
< li> boolsk

For alt annet - Objekt, MovieClip, XML, og så videre -. vi holder oss Post-it lapp på selve elementet

(Detaljene er litt annerledes i Javascript og C #, men samlet den samme ideen gjelder.)

Så la oss komme tilbake til vår tidligere spørsmål. Når vi skriver:
Var listOfNames: Array = venner;

... hva skjer

Igjen, vi vet at Var listOfNames betyr "få en ny Post-it lapp og skrive listOfNames over? topp i pennen ". Og nå vet vi at Array betyr at vi kommer til å stikke av Post-it lapp til noe (en perm), heller enn å skrive noe på post-it med blyant.

Tidligere når vi har gjort noe lignende, har vi kopiert innholdet i en Post-it lapp på en annen. Så her bør vi få et friskt nytt bindemiddel og kopiere alle sidene fra venner bindemiddel inn i det?

Egentlig, nei! Alt vi gjør er stokk denne nye listOfNames Post-it lapp på samme bindemiddel som vennene Post-it lapp.

Nå, venner og listOfNames hver refererer til nøyaktig samme utvalg
. Så hvis vi skriver:
listOfNames [0] = "Emmett";

... da venner [0] vil også
være Emmett, fordi listOfNames [0] og venner [0] referere til nøyaktig samme side i nøyaktig samme bindemiddel! Og fordi den siden bare inneholder en String (som er en "primitiv" type, husker), så vi har bare slettet det som ble skrevet på den siden tidligere og skrevet Emmett der i stedet.



So What Betyr null Mean?

Jeg har sett som dette, er null ganske lett å forstå. Denne uttalelsen.
Venner = null;

... bare betyr "fjerne venner Post-it lapp fra hva det er i dag fast til"

Vennene Post-it fortsatt finnes
, det er bare ikke fast til noe. Så hvis du skriver:
spore (venner [0]);

eller
venner [0] = "Henry";

... så får du en feil, fordi du er prøver å referere den første siden av bindemiddel at vennene Post-it er fast til - men det er ikke fast til noe

Så, for å være klar, sette venner = null påvirker ikke binder det hele tatt! . Du kan fortsatt få tilgang til det helt fint via listOfNames. Og du kan selv skrive:
venner = listOfNames;

... å gå rett tilbake til den gamle situasjonen:



Garbage Collection

Som jeg sa, sette venner = null påvirker ikke binder direkte, men det kan ha en indirekte
effekt.

Se, hvis det ikke er noen Post-it-lapper fast til bindemiddel i det hele tatt, så er det ingen måte for alle å få tilgang til perm igjen. Det vil bare ligge rundt, helt utilgjengelige. Men å ha alle disse permer (og andre gjenstander) liggende rundt, helt forlatt, er en ekte sløsing med plass -. De fylle opp datamaskinens minne

Det er der garbage collector
kommer . i Dette er et verktøy som med jevne mellomrom sjekker for eventuelle "tapte" objekter, og kaster dem i søpla - og når de er borte, de er borte for godt; hvis en matrise er søppel samles deretter alle sine sider er også

For de fleste praktiske formål, dette påvirker ikke deg i det hele tatt.; objektene bare bli søppel samles om de er tapt, og ute av stand til å bli funnet av koden din. Hvis du har mye av disse liggende rundt, så du kan merke en liten forsinkelse nå og da, når søppelsamler gjør jobben sin (det tar litt tid å aktivt samle søppel). Fordelen er at dette oppklarer mer plass (minne) for programmet.

(Hvis du vil vite mer om dette emnet, les Daniel Sidhion poster på søppelrydding og objekt pooling.)



Arrays av objekter

OK, det er enda en stor begrep å forstå - og det er den mest komplekse man ennå

Tenk på dette tekstutdraget:
Var firstFriendDetails: Array = [. ,,,0],"Bill", 20]; Var secondFriendDetails: Array = ["Marty", 16]; Var thirdFriendDetails: Array = ["Ted", 20]; Var allFriends: Array = [firstFriendDetails, secondFriendDetails, thirdFriendDetails];

Hvordan pokker gjør at
arbeid?

La oss starte med hva vi vet. De tre første linjene er enkelt; for hver enkelt vi:..

Få en frisk bindemiddel

Sett inn en side med venns navn skrevet på den med blyant

For nsert en annen side med venn alder skrevet på den med blyant.

Få en frisk Post-it og skrive riktig etikett øverst i pennen.

Hold Post-it til bindemiddel.

Som for denne linjen:
Var allFriends:. Array = [firstFriendDetails, secondFriendDetails, thirdFriendDetails];

... vi kommer til å trenge litt streng og noen tape

Vi kan tenke på som en linje som tilsvarer dette tekstutdraget:
Var allFriends: Array = []; allFriends [0] = firstFriendDetails; allFriends [1] = secondFriendDetails; allFriends [2] = thirdFriendDetails;

første linje er enkel: få en frisk bindemiddel og en frisk Post-it-lapp, skrive allFriends på Post-it-lapp, og feste det til binde

Som for den andre linjen.
allFriends [ ,,,0],0] = firstFriendDetails;

Husk at jeg sa at hver side i en perm er som en Post-it lapp, bortsett fra uten noe skrevet i pennen. Hvis den første siden var en Post-it, så vi hadde rett og slett feste den til forsiden av firstFriendDetails bindemiddel, ikke sant?

... men det kan ikke være både på forsiden av som bindemiddel < em> og Selge inni den andre bindemiddel. Så, i stedet bruker vi streng:

Samme for de to andre:

Så når vi ønsker å vite hva allFriends [2] refererer til, vi bare åpne allFriends bindemiddel til den siden og følger strengen -. som selvsagt fører til thirdFriendDetails bindemiddel

På samme måte, for allFriends [1] [0], ser vi først finne ut hvilke bindemiddel allFriends [1] viser til, og så se på den første siden av at
bindemiddel ... så allFriends [1] [0] er Marty!



Loops

Nå setter all denne informasjonen sammen, og bærer det i bakhodet når du leser dette tekstutdraget:
Var venner: Array = ["Bill", "Marty", "Ted", "Emmett", "Henry"]; Var currentIndex: int = 0; Var currentFriend: String; while (currentIndex < 5) {currentFriend = venner [currentIndex]; trace (currentFriend);} Var lastFriend: String = currentFriend; trace (lastFriend);

Hva om vi endrer verdien av currentFriend innenfor sløyfen
Var venner:? Array = ["Bill", "Marty", "Ted", "Emmett", "Henry"]; Var currentIndex: int = 0; Var currentFriend: String, mens (currentIndex < 5) {currentFriend = venner [currentIndex]; currentFriend = "Herbert"; trace (currentFriend);} trace (venner [0]);

Hva om tabellen inneholder ikke-primitive objekter (movieclips, bilder, tabeller, 3D-objekter, uansett)
Var venner: Array = [firstFriend, secondFriend, thirdFriend, fourthFriend, fifthFriend]; Var currentIndex: int = 0; Var currentFriend: MovieClip; //eller ": Image" eller ": Object" eller ": Array" eller whateverwhile (currentIndex < 5) {currentFriend = venner [currentIndex]; currentFriend = sixthFriend;} //Hva er verdien av venner [0] nå

Til slutt, hva hvis matrisen inneholder andre arrays, som i seg selv inneholder primitiver
Var firstFriendDetails: Array = ["Bill", 20? ]; Var secondFriendDetails: Array = ["Marty", 16]; Var thirdFriendDetails: Array = ["Ted", 20]; Var fourthFriendDetails: Array = ["Emmett", 50]; Var fifthFriendDetails: Array = ["Henry" 36]; Var venner: Array = [firstFriendDetails, secondFriendDetails, thirdFriendDetails, fourthFriendDetails, fifthFriendDetails]; Var currentIndex: int = 0; Var currentFriend: Array, mens (currentIndex < 5) {currentFriend = venner [currentIndex]; currentFriend [0] = "John"; currentFriend = ["Herbert", 29];}

Hva synes du om verdien av venner [3] [0] vil være etter at



Andre Bits and Pieces
Her er noen andre viktige merknader du bør vite:

Objekter

I AS3 og Javascript, Objects er som Arrays bortsett hver side er referert til av en etikett i stedet for ved sin side nummer . Så du kan skrive:
Var detailsOfBill: Object = {}; //"{}" Betyr "å lage et objekt" detailsOfBill.title = "Esquire"; detailsOfBill.bandName = "Wyld Stallyns"; detailsOfBill.allNames = ["Bill", "S.", "Preston"];

... og dette er slags
som å få en frisk bindemiddel, stikker en detailsOfBill Post-it på forsiden, og fylle den med tre sider. Den første siden har etiketten tittelen skrevet øverst i pennen og ordet Esquire skrevet på den med blyant; den andre side har etiketten bandName i penn og Wyld Stallyns i blyant. Den tredje side har etikett allNames men har ingenting skrevet på den med blyant; i stedet, en streng fester det til en annen, vanlig bindemiddel, hvis sidene er ikke merket: den første siden sier Bill, sier den andre S., og den tredje sier Preston, alt i blyant

(For å gjøre ting. enda mer forvirrende, arrays er teknisk sett en spesiell form for Object. Og hvis du tror det er ille, kan funksjonene ses som en type objekt, også! Men det er et tema for en fremtidig artikkel ...)

Mer om Garbage Collection

Jeg sa at objektene er søppel samles om de ikke har noen Post-it-lapper fast til dem, men dette er en overforenkling. Hvis en side av et bindemiddel poeng til et objekt via streng (dvs. hvis myArray [0] = myObject eller lignende), så at objektet vil ikke bli søppel samles. Samme gjelder for hvis en side med en perm punktene til en annen bindemiddel (array), eller hvis siden av et objekt bindepunkter til et annet objekt bindemiddel ... og så videre. Det gjelder selv om den eneste måten å få tilgang til objektet er gjennom en Post-it stakk til et bindemiddel som har en side som er knyttet til et annet bindemiddel, som mange lag dypt som du ønsker å gå.

I utgangspunktet, søppel samler bare samler en vare hvis den ikke kan nås gjennom andre variable.

Dette forklarer hvorfor objekter som er på skjermen vanligvis ikke kan objekt samlet. I AS3, hvis en MovieClip eller annen type Displayobject er på listen skjerm, så er det automatisk lagt til hva er egentlig en skjult rekke visningsobjekter (som du kan få tilgang til via getChildAt ()). Lignende strukturer eksisterer i Javascript og C #. Så hvis en grafisk er på skjermen, og du fjerne alle referanser til det fra variabler, matriser og objekter, er det fortsatt vil ikke bli søppel samles til du fjerner den fra listen displayet.



noen spørsmål?

Jeg håper dette bidrar til å klare ting opp. Det er absolutt et forvirrende begrep når du først kommer over det: noen variabler faktisk inneholder en verdi
, mens andre inneholder bare en henvisning
til et objekt. Ikke bekymre deg hvis du ikke er 100% sikker på nøyaktig hva som skjer; det vil gjøre en mye mer fornuftig etter litt trening (og noen feil!).

Men hvis du har noen konkrete spørsmål om det, bare stikke en kommentar nedenfor og jeg skal gjøre mitt beste å svare.

Takk for lesing!