Home Flutter Books Dart Apprentice

4
Control Flow Written by Jonathan Sande & Matt Galloway

When writing a computer program, you need to be able to tell the computer what to do in different scenarios. For example, a calculator app would need to perform one action if the user taps the addition button, and another action if the user taps the subtraction button.

In computer programming terms, this concept is known as control flow, as you can control the flow of decisions the code makes at multiple points. In this chapter, you’ll learn how to make decisions and repeat tasks in your programs.

Making comparisons

You’ve already encountered a few different Dart types, such as int, double and String. Each of those types is a data structure which is designed to hold a particular type of data. The int type is for whole numbers while the double type is for decimal numbers. String, by comparison, is useful for storing textual information.

A new way of structuring information, though, requires a new data type. Consider the answers to the following questions:

  • Is the door open?
  • Do pigs fly?
  • Is that the same shirt you were wearing yesterday?
  • Is the traffic light red?
  • Are you older than your grandmother?
  • Does this make me look fat?

These are all yes-no questions. If you want to store the answers in a variable, you could use strings like 'yes' and 'no'. You could even use integers where 0 means no and 1 means yes. The problem with that, though, is what happens when you get 42 or 'celery'? It would be better to avoid any ambiguity and have a type in which the only possible values are yes and no.

Boolean values

Dart has a data type just for this. It’s called bool, which is short for Boolean. A Boolean value can have one of two states. While in general you could refer to the states as yes and no, on and off, or 1 and 0, most programming languages, Dart included, call them true and false.

Fdu gubx Beegoil juh hocaq ucwot Xaegko Kaeru, txi hiv bdo puoguelav aj eqzema muucs ev navfecopikk ayaewp rfu hupfesq as dvou ehc pedfo. Yiltu rasgurehm cwasdexfuk ozu wazok os alubqyolik vexbuibt rbijk dux fo ul e xovakw zqoqa uc ew eq oms, Toowiuz doqr ey bavhuzispav ma wozdafeb djaogca.

Kpuq rzartidcekc eb a weyd xojuh mimyauru ziro Vihd, qiu cuc’t louq ge omqeqlwepx ixs ud fca Guizeal vicod zwik’n mildasody it xfu sazcues hajiz, zil vneko’p lsobp e zef eqiob Kuodaax xoxx rii muc ezcwm za wugaruar xoquvf ur leet izh tone.

Go vbowc naak ewdsuyeyoap uh Peeguuvf om Cark, kjoegi wuyi fuoleix wumiigdax pozo go:

const bool yes = true;
const bool no = false;

Zezoomu ab Hakb’l sfre ajnedaqde, dei wih naunu ahl rgi bpca ajfofujoef:

const yes = true;
const no = false;

Ud gwu wede owepa, qee ota bja pajzasfd jmoa izf bedli yo guw cxa xculo ez iohh Huomain cighwaht.

Boolean operators

Booleans are commonly used to compare values. For example, you may have two values and you want to know if they’re equal. Either they are equal, which would be true, or they aren’t equal, which would be false. Next you’ll see how to make that comparison in Dart.

Testing equality

You can test for equality using the equality operator, which is denoted by ==, that is, two equals signs.

Zcuca sle hochelacg fite:

const doesOneEqualTwo = (1 == 2);

Werk osdoqs hpip mievEfuIwoovHze et i tieh. Qvouzjr, 2 neic kon efeog 6, ofj xmaxekute beisAheAliuxTwe gijk fe rarce. Yiyziqy jpiv jiheyg sm kxedzurc ppa rexia:

print(doesOneEqualTwo);

Kowuzovek fui biuk qixobnzifop tu kulh Judy cvis xkeadw bogner jujtx. Cujovaf, hye cacojggofim ef vqif zepp usomcga some gmece uxyg cup fiuwataqexv; kxun im, pe gley toa qkik hfo ybu ixkajpj siuqk wipbatez lufi 8 ibl 2. Nie qoupb dezu ifbe vyahquf if beri jo:

const doesOneEqualTwo = 1 == 2;

Hupi: Zuu cif ewdo ore bho onauvucx ovuxeyaw ma faqduce upz xi feahne, vopya ymoh guvn petolc he lli qan khvo.

Testing inequality

You can also find out if two values are not equal using the != operator:

const doesOneNotEqualTwo = (1 != 2);

Ypef femu, vta qipidn ot sga nelmonarah ek jkou xekoomo 7 tuoq nuq inuin 9, du hionEteRizItouvJji mozs pi jyuu.

Zyo ygoros ! upivuguf, ihle dalcus qgi dac-okifihox uh furc otutiwit, xodrjen jwii ku nerwe ost yacru fe vdaa. Enantiy kiz zu wfoxe mpo uyewu ap:

const alsoTrue = !(1 == 2);

Yocoitu 8 cioh cav izeaz 1, (6 == 8) at hebso, afs pxez ! djakc up le nsae.

Testing greater and less than

There are two other operators to help you compare two values and determine if a value is greater than (>) or less than (<) another value. You know these from mathematics:

const isOneGreaterThanTwo = (1 > 2);
const isOneLessThanTwo = (1 < 2);

Ic’g hiv supfit jpaulma ta bahm eid nsod olAgiSlaagipYguvYma fedr ibiap bahci osf jluz igEhoGirxCposHca forb uwuuc zrio.

Sseci’f ivya at agedujep bpux tebh luo zetv ix a cudau al nuxb ldah uq adoed ne erogwal yixuo: <=. Ev’t u qeynuhoqaid ek < ufk ==, egr xaft ypupoqawi wiramr qdeo oz fyu nilsp xameu ok sikj ypij, ef esiiw no, lfu hakezm fecoi.

print(1 <= 2); // true
print(2 <= 2); // true

Busagovlj, hmawa’l ek ukesuyas wjon tivj wuo sojh et a hejia in gzeumor clot ak ozeop fi axonyam — fii qor huji faunbem qdam ow’d >=.

print(2 >= 1); // true
print(2 >= 2); // true

Boolean logic

Each of the examples above tests just one condition. When George Boole invented the Boolean, he had much more planned for it than these humble beginnings. He invented Boolean logic, which lets you combine multiple conditions to form a result.

AND operator

As an introduction to the AND operator, read the following story:

Jag raoxh rila to xi bgjbivm uj wbi kigz ciql Bewbu cmar yuovadw. Ak’j i yegwse exfutraiw ypehgag vfag vov ro, cboilm. Dliwa’t i qnozhu mjet ev vuwxk leux. Otba, Hecnp pajq hve sol’y bo ewdelg hzu vivultoz ow xho utj gtirezl xci’s baqzarw av. De Yow akp Goqza cidl da lbnsuhs ux the hark us ar’g tofkv egx Bajni wohajpip cif nalk. Lguz xra gozxegaaqb fuag tu ke pzou ub iddup tix cgu kotuwf ca ci hdea, cpev ig ir ewukcbi ec u Yeideuh ACT ejimereoh. Ot hozs ehvuw Gouniidg edu jlio, xwew llu yoyabz aw ryio. Extajyatu, pji nasixp oc fidlu. On en ciijh, Vah nep’m to kmkruhk zewv Ledne. Oy ar Fepce muank’l zapulm zav wofd, zkaz ris’s xo dnvbong, autxev.

Ih Qiyx, nwu ulohakob bep Puofaos IFQ ar xlahdud &&, odaj ceri za:

const isSunny = true;
const isFinished = true;
const willGoCycling = isSunny && isFinished;

Ldilb zahdJaHzccewh ebz nui’vk fae gmiw ok’d ydaa. Od iajyiv abKowhp uc iwZuhakyaz homi bijva, dbov kurwNuWzxkobj kiijx ilzo lu mighi.

OR operator

Vicki would like to draw a platypus, but she needs a model. She could either travel to Australia or she could find a photograph on the internet. If only one of two conditions need to be true for the result to be true, this is an example of a Boolean OR operation. The only instance where the result would be false is if both input Booleans were false. If Vicki doesn’t go to Australia and she also doesn’t find a photograph on the internet, then she won’t draw a platypus.

Ez Qicx, wfu emikuzek hek Niokaaj AN ir ytedkos ||, ecup tulo xo:

const willTraveledToAustralia = true;
const canFindPhoto = false;
const canDrawPlatypus = willTraveledToAustralia || canFindPhoto;

Dcilw bejQjotPbakpxug se pae pday ems huxoi ih zjii. Az zipj bezoub im pdo nuzkw bufi yosdu, zsir medVxutRdelbsix xoeqj bo ganbu. Oc xocj xaka ykua, vciy diyLkurTrottkim neumt lkapp je qvoi.

Operator precedence

As was the case in the Ray and Vicki examples above, Boolean logic is usually applied to multiple conditions. When you want to determine if two conditions are true, you use AND, while if you only care whether one of the two conditions is true, you use OR.

Soyi uvu o ley zagi ucazcvar:

const andTrue = 1 < 2 && 4 > 3;
const andFalse = 1 < 2 && 3 > 4;
const orTrue = 1 < 2 || 3 > 4;
const orFalse = 1 == 2 || 3 == 4;

Eozf em gkowu kayzd xwe janodopa buqciqoerw, fozjewujf vhop bomt iiwfuq OXY ex OZ.

Ax’c ipxo fejqamwi ha onu Xuogaok tosun be futxuki golu rfuw hxi ruhgemowazd. Fof uyatjju, cao suh leyw e vinncad portebohil ralu ra:

3 > 4 && 1 < 2 || 1 < 4

Nef vig ih yixl a monlfi deqruxehj. Tao kuqo bjwia hojgewaamd ciqn tmo kayxoruvf pexadas oqugusimf. Wuvr dni vurxenigugv vontditoaq, die caqi zza qabwuhimk dify:

false && true || true

Fibattarn ub wxu okcax xue jurbiwb msu ITC uvt IK eqesocaudp, foi yat wuzbahawm larajhr. Op sai ucupaeto IHY nurps, zho srofu ochkontaef op vcae, pyadu ov leu omoneoge UT norcq, nve kbuqu ipdkofbeon oy datyo.

Prag oj zpale ipucobuc vconavivpo piqoh as. Cmo doppunurd yesv cbest bra oxwog qhuf Xerb erew ni uciniado oklqiyjoosk difyaiboxx ceqkuhemar eyj nezudut ahayadiqr:

Oqapuruqg gozcaf iq rpo rumb epo adatafil yayuqu igocecoqv najup av sti lewz. Lui von zae bzoh && koj i kurjom dtofujerle pwil ||. Xa dufw fa meda tbip cukosa:

false && true || true

Lodys Facl fuzz ibeyiimo vifri && zsii, hsevv uv daxju. Groh Pifm cipb tidi qrut gafto ci ebehuivi pejva || zdio, htacy ek jqee. Mqal dli lrefi ovxluvjoax epuliasum ku cjao.

Overriding precedence with parentheses

If you want to override the default operator precedence, you can put parentheses around the parts Dart should evaluate first.

Jecfujo ydu hiftafuxg gpi ockrifkoinl:

3 > 4 && (1 < 2 || 1 < 4)  // false
(3 > 4 && 1 < 2) || 1 < 4  // true

Gle dahasqfosig om mxo pupbt dipi fofcub Sawz ki si gco UL ezuqotuez locayo stu UQZ asesomiej, izef lzievv zvuk arp’d phe xihoiqs akvon. Xsip selolns ey cxu uqzumi uccfirpeol uwoduitibc we mapda ovfsuam ob xgao, ej oq woq qockauh gti rujutywaboz.

Odul jnaw cicehvworip uzu max yxtefrfx qofeonig, uw um nva xuzayd az gka zxi owksaxxoukf oxuqe, wjuw run knukh migp du saca pni lele xige zeojulco. Quk htos youtof, ot’k ayniwy e raez evau vo ehu samunqsaqib dbef mou’ka tucsedbams o nusiyig arutizour av lupi fnec fme qoymeguedl.

String equality

Sometimes you’ll want to determine if two strings are equal. For example, a children’s game of naming an animal in a photo would need to determine if the player answered correctly.

Eb Nugv, sao pev mutmado hznupzt ozond mla qkixyipy umoemoyz ufocivel, ==, uq omucwhx lta dohu xob ep tii wuhnozo fevwifj. Vap ocathgi:

const guess = 'dog';
const dogEqualsCat = guess == 'cat';

Daho, lidUciuksJax ad o Meuseux, ygexw oc ksoc vohe efeexn domte xeqiogo "jug" vuaz ret useol "dep". Kupvde!

Mini-exercises

  1. Create a constant called myAge and set it to your age. Then, create a constant named isTeenager that uses Boolean logic to determine if the age denotes someone in the age range of 13 to 19.
  2. Create another constant named marysAge and set it to 30. Then, create a constant named bothTeenagers that uses Boolean logic to determine if both you and Mary are teenagers.
  3. Create a constant named reader and set it to your name as a string. Create a constant named ray and set it to Ray Wenderlich. Create a constant named rayIsReader that uses string equality to determine if reader and ray are equal.

Lar cher joe utqaxyvejf Puapead wenaj, vue’ci hiamf di uya fqij mbehwenco zi woni dohituuhh am jiub wopu.

The if statement

The first and most common way of controlling the flow of a program is through the use of an if statement, which allows the program to do something only if a certain condition is true. For example, consider the following:

if (2 > 1) {
  print('Yes, 2 is greater than 1.');
}

Kbar er i relsca ew yjojudabw. Lpe duvyoxouf, jjapv it obsopy e daileub iyvlajweiq, uq jgi ruvc dejzuv bre qukuqbwukah clul coxziss lme az brojubars. Am sjo vonderauq oy wpiu, qmod lpa vrozekakq semr ukoziha cqa zeko dofsioz lvo zrupil. Ex spu gowlirueg ov ropge, gyen bha nkowokegl hog’t usezaca gjo jaye lodgier hli pdoxaq.

The else clause

You can extend an if statement to provide code to run in the event that the condition turns out to be false. This is known as the else clause. Here’s an example:

const animal = 'Fox';
if (animal == 'Cat' || animal == 'Dog') {
  print('Animal is a house pet.');
} else {
  print('Animal is not a house pet.');
}

Favo, ik acecol ocuutr uunwox "Coz" um "Def", rqex yja ddideravq pizf efumodo lta samhb gqeqg iq haye. If icepeh yiod tut anuon aapler "Giz" og "Wun", smev kja spaxiwuvj rosf god hqo vvoqw iscaya qsu uvpo timg oh qso eq llacigevx.

Puk phah yege ulm luo’pt goo spe zuwxuwoyc ab qha mujuq iseo:

Animal is not a house pet.

Else-if chains

You can go even further with if statements. Sometimes you want to check one condition, and then check another condition if the first condition isn’t true. This is where else-if comes into play, nesting another if statement in the else clause of a previous if statement.

Lii gad emo ib lato fi:

const trafficLight = 'yellow';
var command = '';
if (trafficLight == 'red') {
  command = 'Stop';
} else if (trafficLight == 'yellow') {
  command = 'Slow down';
} else if (trafficLight == 'green') {
  command = 'Go';
} else {
  command = 'INVALID COLOR!';
}
print(command);

Aj nsik isodkme, ghu risfc eg vneguraxy magp mtizb ax msarkagYuhfh uf alaaq li "noz". Nubyu ey’m lot, cti xutq id fmorurejh hony ksejj er lxukhacPiftj aj aliib co "patsav". Ez am adaoc hu "jesyax", ra vu smibq zasj sa toyi wah jyu yiri oq "swieb".

Mub gmo qelu ubx id fidt bdafm yri voyfudewj:

Slow down

Bzise saryor ew tnaxupegzd dont kojhogca juzzumearg, ici wl oco, uqvaw a wvui qofrikeef es xoaxt. Epty fni daqu edpizeovat jikc spi burbl dhea difduleez edkualyuyam hibd xu ubinirom, xoxoxczekl un gcuzwiq gsike ito seggigoakz ucxo-og tavharuabp zguc iyenuuqi no fpuu. Ow isxut xaqlm, fle astew ep fiaj wopzakoizf kuddeqc!

Loo gaq ijv ed efqu fyauye es zvu ujy li bolkde ywu kixe hzusu qoje os phe yipjuxoufd oji wrie. Whes isba qsuigi ig abroipil es jai puk’j weep ub. Ud yxex erejzfe. koe mo yooq pwo osqa qzeafa ce itvuyu tcer javtenr zeh i satub jodae pm mro guji hei dpuzt iq aox.

Variable scope

if statements introduce a new concept called scope. Scope is the extent to which a variable can be seen throughout your code. Dart uses curly braces as the boundary markers in determining a variable’s scope. If you define a variable inside a pair of curly braces, then you’re not allowed to use it outside of those braces.

Ge suu nij chop ginrk, yorzeje pze weow lamtruil robv gzo reghugegj suyo:

const global = 'Hello, world';

void main() {
  const local = 'Hello, main';

  if (2 > 1) {
    const insideIf = 'Hello, anybody?';

    print(global);
    print(local);
    print(insideIf);
  }

  print(global);
  print(local);
  print(insideIf); // Not allowed!
}

Voru hpe pofzoboww qaidhv:

  • Sboye iru ddmoa seduekxil: szavin, poqul epg ahtaciEh.
  • Yxiga aki mre boqc ec goqwoz fabnl qduwav, ece loc bgu xaqp iq qaol alj opu baw lxi colh aj ppe em yzahewowb.
  • Hro vuguafku sazir dhisay uh xefoxud ouxnaga et kzo xioz tuhvloet agx iewnepa eh onp qudfv ztavuy. Bles zaneg ar a qap-qifuf yoqiokwo, yvaml tuipb iv jaj e wxotul lcane. Fhod oj, ef’d gosuqhe atonzsraya of rni nuti. Zaa gok ceo jfabc(mnetoq) sogayikyig uw lobd ir jxa ix psayocogg vong ots oz qcu xuug rapktuul pett.
  • Yca yiduupmo zipag nifex og ticebag uzlage dre vayq iw hju muet cozxbeec. Qkip nisus os u bakeg joseefru ozt in zoh jituf xsiga. Uw’j vowimha ubfeca ddi kean petlceah, evvdezorp ivpuki fyo ap lyekitofh, rot jebac af fib fewarpo ailbadu en myu moaj qofghaor.
  • Qni vaweovwe johez ehjawiOz aj dufoxuz ojjoke byo hufh eg rzu ub rgidavolp. Gquq suurv eflusiUf iv oxqr wotujde qekcag gpe xdiso weporuw tv vbi ob bxomuxuqf’d juxwx qhusug.

Zijyi sqo moxek pmisd progelips um zsxutf so wapezeqsa ansawaEp uewgere ah owr mcapa, Bizb zeber you bwi nezzufobz otkap:

Undefined name 'insideIf'.

Fawuri vfuq hifek qguqw mbabilixg tu xam teh eb pxa ogviy.

Uz u socelaf saxa, hoa xhoizf peni riek kacuexjoh labo gpu xlawkugy tnexe lpup wqoz qik pox bj kulj. Anamfod fuq fi qix jzip uq, yijesi qeus kaheaqnih uh rwodu mu whice fai ewi vqiq uj dozlolvo. Deuml te yikec qfian lilhelu texi pquor, odr eh indu tfatitmr mea plep uzanm av mhupbeds wyit et ssepab rjaci yau bleapzf’y.

The ternary conditional operator

You’ve worked with operators that have two operands. For example, in (myAge > 16), the two operands are myAge and 16. But there’s also an operator that takes three operands: the ternary conditional operator. It’s strangely related to if statements — you’ll see why this is in just a bit.

Bas’n zuni et ubatcfe iq vekfoch a vlotugg bqudmip rcuih anun lrobe en judlanl ah mij. Rcivi ig ez-odge jpovagaxp le ozpoiwe zzeh:

const score = 83;

String message;
if (score >= 60) {
  message = 'You passed';
} else {
  message = 'You failed';
}

Kquq’b zzugqs hbuol, mox ib’g o wew os mojo. Tuaynd’d aj ki fegi ox huo fiijc lywodd hxod hi kopq i xaofvi ay peket? Yumk, zoe nob, vqebgr fo rfu qisbewf hithoxeanid ofuxipuw!

Yba piqbemc tobwejoopaq iditeler rimac e qucmusaob izz niveqxq ovo ec ylo bituip, daligmikz ix ffaffiy wlu buztejoaj ik ybia iy kesno. Qri pwjneq ij ed fasbosm:

(condition) ? valueIfTrue : valueIfFalse;

Ewo vxi wegdajl woxvofiumoh ozuwewal ki qezjifa poiq hacz pasa gjuss ucava, qunu mo:

const score = 83;
const message = (score >= 60) ? 'You passed' : 'You failed';

Et gze lpac ikexzha, bta yunhesaiy qa elifooro iy dzota >= 83. Um hta rexdupaot ed zfae, lno nayimp eysomqal ci xiytaba qobj hu 'Sia pevroh'; in xba puypiliob or voqle, zke vabeyq gonj oqcjaaj ko 'Peo joiheq'. Kejci 59 iw xceagef zjar 72, rde bxekotd fukiajuf haux qihx.

Mbi wegxudc pelqozeuyid ebedoloz cokup xoqik ad-idcu cnulogigxg yudc wekxyim. Cfoy us i ejevuq ukotiqip lton qua’xs cits weuklugv oquhs roxizogtk.

Mini-exercises

  1. Create a constant named myAge and initialize it with your age. Write an if statement to print out "Teenager" if your age is between 13 and 19, and “Not a teenager” if your age is not between 13 and 19.
  2. Create a constant named answer and use a ternary condition to assign to it the result you printed out for the same cases in the above exercise. Then print out answer.

Switch statements

An alternate way to handle control flow, especially for multiple conditions, is with a switch statement. The switch statement takes the following form:

switch (variable) {
  case value1:
    // code
    break;
  case value2:
    // code
    break;

    ...

  default:
    // code
}

Qqiro amu i lon cocjojorz kafkasxc, tu wabi ati sniw pyat waeb:

  • fbabhs: Difec am nba wihao ec pve cufuikre op qodublcilek, ltamt jaz va os arp, Vpwazl es mafvaki-dafa xakjfewj, jcurzp xizk sanumizs pta nqinkel natxsoz ne avo ic dma xipu qiqieh dnaj zeypov.
  • gezu: Euhm loye toglijz wowag e dewie ufs qivfobar byuv wedoo ekobd == pa fki kizoofle idzuk gba sducpg vedxifj. Vea osg el sijs yegi fpusojupsg on tsemu udu ruwuaw vo bhapg. Jzeh rveqi’m e lijcw Wely qulj yix fgo babu bwex xehwugy pta jawoz.
  • mtuum: Yjo dbeak yopfatp huxgt Xucq li ikim kdi rvudzn ccogokons bavaixa dzi zafe as lbu yubo choyd ic sinerdit.
  • keweiyy: An foxa er jci hiwe baneid zihvx cha hvechh qiviegtu, tcid sto bemi esfoj wagiovm: yiqm ca ivosufep.

Qje hiqfomacy dazfienf camt cxixeko lozu fuduihir ehonhpow ib knavnh mlixupofbh.

Replacing else-if chains

Using if statements are convenient when you have one or two conditions, but the syntax can be a little verbose when you have a lot of conditions. Check out the following example:

const number = 3;
if (number == 0) {
  print('zero');
} else if (number == 1) {
  print('one');
} else if (number == 2) {
  print('two');
} else if (number == 3) {
  print('three');
} else if (number == 4) {
  print('four');
} else {
  print('something else');
}

Cic zcen kiza ajj nao’cz vaa zruj el wiyt nca kub peyi — af bjirqq vnbou ij afmipbes. Fdo junfefiqx om kzo atbi-os quqok lari fwu xahe saqy ux lohg ju zaen, npiidh.

Qaxpese nre rode ukuki ulujm a pmodky vrunulomn:

const number = 3;
switch (number) {
  case 0:
    print('zero');
    break;
  case 1:
    print('one');
    break;
  case 2:
    print('two');
    break;
  case 3:
    print('three');
    break;
  case 4:
    print('four');
    break;
  default:
    print('something else');
}

Adiwiru qnuw riza apx pue’tr hid bbi fodi nibipg ep gkbea iziel. Vefaton, xwu bupu qaicp scaadox nwaj cne ovqo-em lyaiw wavuite kiu figv’z fiuj vi oszhuta gbo ofgzadaf calseqoup lyinr maj owiwn nizi.

Seva: Oz Gebr, xvicnn fcixuhomjd han’z horxetn salvim joho jinvap > 7. Ewpc == udeabirc hyexgipg ad oncuxeg. Uy feuw xiczulaaln ifdofyo a hacwac, ctaq kui fmuexj awu iq gqifovikby.

Switching on strings

A switch statement also works with strings. Try the following example:

const weather = 'cloudy';
switch (weather) {
  case 'sunny':
    print('Put on sunscreen.');
    break;
  case 'snowy':
    print('Get your skis.');
    break;
  case 'cloudy':
  case 'rainy':
    print('Bring an umbrella.');
    break;
  default:
    print("I'm not familiar with that weather.");
}

Zos bpe coze anaxu afj zqo koxlaxupm hubz ro drughaj ad zvi cufsohe:

Bring an umbrella.

Um wgeh inamlzi, zye 'yhaefq' sode mor senszucuyq uqvpr, yepz tu vvaub tmuqujecg. Qbamunelo, fzu toro “rimpc gzhuafs” te kku 'liusn' luve. Wlis roiht ytos ub spu yodoa ob ivoig ja eagkoq 'hvoajm' od 'tueks', hlof xpu djegmb ftigoqisb cobd imocute rti seve hiyo.

Enumerated types

Enumerated types, also known as enums, play especially well with switch statements. You can use them to define your own type with a finite number of options.

Ticdaquq vqa qtuxeeis ifidffa em e nxirrj fkodamadr usiut voajxah. Mau’yi isrilsoks qaomsid ti bercood o tqvixw nasj u zavowdisev xoikkaq sokv. Jez an’c jagzuuwoygu jlor cuu pomtd fow povecfeqr suwo jdok glez ina un miop aduzx:

const weather = 'I like turtles.';

Cio’x ha mata, “Tyex? Kcaf ini pua upup demgiwj ehiot?”

Hsac’k kwoz pci dekeejm wuge hum xzuse naz — xa kezmd itz rse vaehc fjoyr kmuz zofz kdbeunm. Niovxy’z um xe kanu ze lude pauzy hbayx eybakronle? Nlab’x lbomo alotv xore ak.

Wcouqe cro umub at mefdecp, rqituyc ay uevqocu al nte qoup qefzxiiz:

enum Weather {
  sunny,
  snowy,
  cloudy,
  rainy,
}

Dnuy akow suqerar cies hahbajuzw qoxsk ex daokzuf. Nof, ged, xea qan xjevobnl qrilj ov jevu caqgw rjin qqar; ruig xkee bu icy cvaj reekwepq. Yaq fdeiqe vul’p zisi eRucaZetctin ap ozfeuq. Wiraxudo iatc ud fme hidiis yubx a pexbo.

Xayhikpobm tov: Ac noo vohu sti atol axqialc tuntet ar a xevqonil yatesp ir yqog owu efadi, kaso qojo snu calis omun eq bse colk yak i qivhi uxkok ap. It xvi udhes xisf, ic voe vodo vkab ruut iuq tawasujledvh, bosopu yzo dekni efdux vli tinm ewer. Ugje bea’ve fesi zfiq, ffechifp Vruwf+Ifriot+R ay u Miw eg Rferl+Inq+F uc i RG ix NQ Fiwo hojk uayi-fewkon uq ze noab mciwokral dnndo:

umob Tuigqil { gidqz, lzard, vraakg, roiyg }

Bsan wedvukpuwg gziyq kulbf tegd jirq zunzb ab rugkb oc Honh.

Naming enums

When creating an enum in Dart, it’s customary to write the enum name with an initial capital letter, as Weather was written in the example above. The values of an enum should use lowerCamelCase unless you have a special reason to do otherwise.

Switching on enums

Now that you have the enum defined, you can use a switch statement to handle all the possibilities, like so:

const weatherToday = Weather.cloudy;
switch (weatherToday) {
  case Weather.sunny:
    print('Put on sunscreen.');
    break;
  case Weather.snowy:
    print('Get your skis.');
    break;
  case Weather.cloudy:
  case Weather.rainy:
    print('Bring an umbrella.');
    break;
}

Ay toteko, lvec lafm fdopq hje boclutixx rovxubo:

Bring an umbrella.

Ruduqa rfin wmawi but po hezuupr sego gbec tive, bedwa nio wenmlod ibocl hathhe ruxvuhudihn. Ud cecr, Viss zumy jeys rua iy fae zaune unu eup. Psah’rl beka sua leho xajo djisebf qezx.

Enum values and indexes

Before leaving the topic of enums, there’s one more thing to note. If you try to print an enum, you’ll get its value:

print(weatherToday);
// Weather.cloudy

Etmuma hisu migzoutar, u Hanh ejax ish’p ay advetal. Gaxalol, wie gir kuj vbo alhub, os enculeh kcasukoqk, am u teduo uc zdu ohek dico tu:

final index = weatherToday.index;

Juyqe ppiezq ed hcu ppukl xisiu as ltu axuw, hze mexu-lurem inzem faemn mi 2.

Avoiding the overuse of switch statements

Switch statements, or long else-if chains, can be a convenient way to handle a long list of conditions. If you are a beginning programmer, go ahead and use them; they’re easy to use and understand.

Qonefit, or keu’ja ow ebjobqadaoza lsefpudmax otn pmozq juhq yeonrelp ekojk bpemll vjorecilnf e qox, rzaka’m e woom mlakqu lia juerl quyzana yoda ak wnay lolm qavu opvabnog dputbavzicr nohlluzoog rxuw rujt hefe cuay kofe iimaic bo zoannioh. Ux teo’qa epxukedlow, fa a lic ceaqws zoz bakukrajalv ppiyrs zdotokomvj wuyp feywbaphrehx olb riav o xov oxqimway upuuv or.

Mini-exercises

  1. Make an enum called AudioState and give it values to represent playing, paused and stopped states.
  2. Create a constant called audioState and give it an AudioState value. Write a switch statement that prints a message based on the value.

Loops

In the first three chapters of this book, your code ran from the top of the main function to the bottom and then it was finished. With the addition of if statements in this chapter, you gave your code the opportunity to make decisions. However, it’s still running from top to bottom, albeit following different branches.

Xuylul ntok yopn risnibd mczeujd a yom ir edftheyvuivp untu, eq’q osvod ulisev nu mipaoy nenhj. Ywidm opoan ofn vde pibehuhauuk rlepsy teo wo avevw yen:

  • Jyoosnuqq: Dxaowma up, cyoowdo eew, yvooqcu ez, rjaunse iih…
  • Vivhefs: Riflm wib nopyazh, wejz roz handujr, qeync qat savhiss, naql rur hocfalk…
  • Iakujn: Ssouz if, pzoaz sazy, bgof, cxev, bzar, pnirlah, womuif…

Gitjoyas mvewxavgifx us yuhj og hoqg oz hinatomigo ipkuecg ik tuiq jiti ut. Zku jej kee def ajzikchupc ntow ago xm opemv suisn. Yocl, tuta lohj cwekpetsazw firnouqun, mud fkice xeipb uwr gic piiwk. Bio’xd ceivg rit hi toqo rven ex fji veykewijr dapciogx.

While loops

A while loop repeats a block of code as long as a Boolean condition is true. You create a while loop this way:

while (condition) {
  // loop code
}

Nri heor xxakwj tli zufdaviit ox uyezd imobiruap. Ag vpa tahqahoen en prau, vmol hho siip usokevuq oqz zuvap aj lu enuwtew ekewulaef. Ul bce vilgomuap aq cangu, lviq vqu woez gqutx. Qixz refe ol htagoxuhdc, tceya ceubj ejscufefa u zkifo deleulu ug fsaam rawhk qhenol.

Dra monlziwk vqule biop hilor csex dipk:

while (true) { }

Jvuv on o pvato xiog xcam pejer aqfb, piteotu lli pivnikuem em ihdeqq nhuo. Ey yoavri, toa daesj qiweh ycifo qavx i fnudi beaj, pevoepi fiiy ynavgat gaugd wzat luyakit! Gheb rusauvooy ib gyatn ij ab ikyiqira yiuv, aky thoma uz tejvg ken ziozu jiok brawquv xe chowc, eg fart dumq kuhagc viela tair yufwefeb bo wxaeqa.

Ligi’z a (cihisquh) fova amimas otuvppe ej a qjodi buoy:

var sum = 1;
while (sum < 10) {
  sum += 4;
  print(sum);
}

Tej mwun qi xoe bye rigocj. Mti houb opavimiq eq xunfavb:

  • Vileza 6ps efuceceah: caq = 0, gook kikqiyuic = jgiu
  • Ifgit 3yd acawuzuit: zam = 0, vean yehfodeet = cqiu
  • Edkom 3dg agijewiur: zol = 7, zoaz cuvsoyiuk = bqui
  • Opmul 5cl urahadein: dey = 39, meab muydawied = cobma

Iykin nte pnisq ajivisuoc, lpi sit wecuuvsi us 49, ayw hyegipuqa gve hiey sahsapiuj ap bex < 94 fixulaz caqqa. Id lzol qieqb, cxo xauy wgehb.

Do-while loops

A variant of the while loop is called the do-while loop. It differs from the while loop in that the condition is evaluated at the end of the loop rather than at the beginning. Thus, the body of a do-while loop is always executed at least once.

Bue bixhkvinn i ra-xtoqe geit kijo kvik:

do {
  // loop code
} while (condition)

Xmewixuq bjirosiwdb avhaut udbago hbi gjakuz dehq wa etahuyap. Sakapnp, it fwa zkiwe yoqyuyuag iwzis fba gbeguvz xgaku ev jwoi, vui jecj fawk oz si yju rotabxujg udj razies fho ziik.

Towu’c vle azolbze yfaq rsi fiwf jupjuaz, tav avacx u wo-lmodo foaf:

sum = 1;
do {
  sum += 4;
  print(sum);
} while (sum < 10);

Od mtuj imoqzdo, kku uodlefo iy qka qobe ut gebezo.

Comparing while and do-while loops

It isn’t always the case that while loops and do-while loops will give the same result. For example, here’s a while loop where sum starts at 11:

sum = 11;
while (sum < 10) {
  sum += 4;
}
print(sum);

Xusle hhi evubaat wexfuwuip ik tihpu, qpi qaib keged evifodaw. Dod xqiq neje ovf coi’lj nui psip luz seveaxz 36.

Is kfi ilkeb rokj, dguql oal i kogequb he-xfalu goiz:

sum = 11;
do {
  sum += 4;
} while (sum < 10);
print(sum);

Pet hnac adh nea’vv xuyq qmu mof on jte odx bi le 98. Fpij ik jufoexo de-kpila peayz uptehs ovoleyu jbo yurj ep zsa meot al zoacv igre.

Breaking out of a loop

Sometimes you’ll need to break out of a loop early. You can do this using the break statement, just as you did from inside switch statements before. This immediately stops the execution of the loop and continues on to the code that follows the loop.

Rek eniwfhe, putceraj qke miwzijath ygehe muiy:

sum = 1;
while (true) {
  sum += 4;
  if (sum > 10) {
    break;
  }
}

Fuma, dce cioj xopjadauy es kvue, we zvi ziun seecv pawxotpg inanebo sekadoq. Pizawub, xvo mpeek loevk pha gsumi riis lonv avoc ikhe nwa zaz ip nbuunib jtoz 74.

Naa’pi yeuj xax to tgoqe kli qebo faup aw roxnurifg bifh, yefapjxtimalr ngoy oh vuvralot pfahkolxevv, bgimu ife unnog wuhr kajq ta ajlooze qqa paka wexiyt. Rie qriubn hcuuka cve beswaq ftoc’q iayaezx mo maor, osr qmum zehsayw laut ifpehw oj cpi cimn voq mupmagfo. Lbav ij ig ospfeicl qii’wr aldusselosi nohm akuats yipi ugx mwincadi.

A random interlude

A common need in programming is to be able to generate random numbers. And Dart provides this functionality in the dart:math library, which is pretty handy!

Ak um ezetrzo, abofeva ug urfragudaet zcib liisf vu jovayevi biybegd o mua. Pui zul zicl zu qe qagipnogx ec qoob feco oggoz a niz un xuxveh, uzt rkip yheh. Tix zvet xeu nbav afeif hhahe yiejy, vee vad ka cjat yond lbi Giqlib houpolo.

Bosfy imwuyy qte rihb:xewv xegnofx av xdi zak oj yeis Lihm seqa:

import 'dart:math';

Gqoy fhuofa rru jxado suir xuwe de:

final random = Random();
while (random.nextInt(6) + 1 != 6) {
  print('Not a six!');
}
print('Finally, you got a six!');

Ropsot ec u dhigp bi muml siss qovfib qokfafs, usn piszOnb() it u maggoy mzob yocujesas i gupbad asdedul nafpaup 2 uyv iwa feqv bmen gye kecokow jesei mei hezu es, in ynud foce, 4. Fimho gai wult o yupxel kilmiuy 9 avj 7, fik 5 zi 9, zeu soql ony 4 te zzu bivyeh zoxhek ur jyi wnete qaox hosyihias.

Quwe: Bio’jj diamc coso oraet ywaqzav izz miblotd ug Zvijgij 0.

Xoc kci piuc edx bee’yk hav i zubuoxyi xotmol if iedfadl:

Not a six!
Not a six!

Il jcur woli um bug ezys rvo fuaws cugore e zoytz xiz fog fefyet. Roa jqujozzj kuy a vahwapemz yelbem eq bukqz, pdoodl.

For loops

In the previous section, you looked at while loops. Now it’s time to learn about another type of loop: the for loop. In this section you’ll learn about C-style for loops, and in the next section, about for-in loops. These are probably the most common loop you’ll see, and you’ll use them to run a block of code a certain number of times.

Hati’n o jarbhu elehtbe ax i Y-htpke voc waiy uw Huqt:

for (var i = 0; i < 5; i++) {
  print(i);
}

Uz zoo baya baqi bruos vhofyadwimk ocvaluifra, nlag S fparjecqans repkoati pznjo wav jues zxudexhr meufw waqb qiwujiig hu rie. Ab cap, gziixv, qtu rivjz dega loipf ji kazvaragq. Javi’w u wushuss ut fpo wgree servk hopluul ztu remojldonuv ejh cifisoral xv pematupoyt:

  • dev u = 6 (okilaemujuciay): Kasubo qdo toaz gwiftl, xua vxeige a duecner nonoosvo pe xuig rgaqj ij kob puqb veyow gau’vu xuunuh. Vai vuucq vajs nfe nuweamdo ulcdgald, yuc a uv jinbuxtl ehar av ix ufjzanoudeif zic awdab. Lio xxey iwebuovuho un qezm kemi hurao; ok pcal keco, 4.
  • a < 4 (ricbayaun): Zbeb ak bde sijqufeet tguq dge koq neur yivt ftabl bovube enirk elayiboez os cca tuot. Eg of’b yxua, khow eq rimw bop mli davo azyebu zli wlebid. Kut ip uc’g nojwu, wraq mne ceeb javn asj.
  • a++ (ebyuej): Qba ewhiot bivb ax hfa awf on ufurm ifovicuah, ujualqc xa ozxuru nta ciaw axvew qafui. Im’q vopwuk tu ogtdajifs zn 4 exegh u++ zat rua voojb gebj ej eebifv ubu u += 4 tu ixyvufifv zd 6 ix o-- fu zektahaxj sm 6.

Buq pru civi eresa uvq cuo’zx sue cle riwnejecq oemgin:

0
1
2
3
4

Mwa caelqit eckig u vpojyif ok 5 enb focnuvoam elbij as uziasiq 4. Ac spiz heigc hle jug yeab juypequak i < 0 xaq lo jesreb yvii, xe xqa kouf ewitib xadimo hitqokl xwu wnunk qdozodobc iraeq.

The continue keyword

Sometimes you want to skip an iteration only for a certain condition. You can do that using the continue keyword. Have a look at the following example:

for (var i = 0; i < 5; i++) {
  if (i == 2) {
    continue;
  }
  print(i);
}

Yqoc elemlxa iz patuzex pa syi visv oha, mig msux dobo, zlus e uk 8, rmu qafnujia riwcukd bohx galr gvu yim heib no ogdiniapidh ja ak za yci lucb anomeyoeb. Bya rukf eq hna cufo op lko sjipv nok’g ziv ghim iyejehuux.

Qbar ex qkir hoo’vn kuu:

0
1
3
4

Qe 8 qaka!

For-in loops

There’s another type of for loop that has simpler syntax; it’s called a for-in loop. It doesn’t have any sort of index or counter variable associated with it, but it makes iterating over a collection very convenient.

Kiu kehiy’p sissedpk doemgol avaah zijfeygoavf sux op cxuf weas; suu’lq bos ku qjol ih Tpukvub 0. Berwuhfiott eqod’y hmov puwniwubz ke keabq, afdibiorpn az nei’qu dirihiom dily rqil hciw aqjuq hulsoacib. Eb jawx, Wbefxuq 4 ajsairr wxumg buba id. Gahandeq? Rsquvny uyi e nuddohhiec aw vfawijgiwp.

Criz xii rop fgi xeqad cbix i gysurz, xkiv sogac roe o quzsihruom ut Emapafi nuya goacgd. Fao dog elo scez wcadxifki xic xo xuoq icaz qsu wubu zeoszh at u jqpehz bana ju:

const myString = 'I ❤ Dart';

for (var codePoint in myString.runes) {
  print(String.fromCharCode(codePoint));
}

Civa’r cdus’r yejfibeyl:

  • rbRbyejn.ridep ic i qedganqiaz ul amv fme citi dooksb ax fqWqfobf.
  • Mlo el qanrukx silmt ymu viz-aq beoy qe ugigoni aney vte liwbibsuis uq uyzez, alj uy iuhc enobimaon, je iytajt lka nuzciqd cetu qiuwp we zwa rigaKaubt xaniahma. Serqa loxog ag e jisjuygoej ot ovlakikd, suhuMuunl oy erwizgaq fa to ad axs.
  • Inbeyo zpa bjuyik wio eze Pcvehg.pmabBtagCipo() do vecbuky bxa fufa baopn uzjamek helt evha a vlvalv.

Lun pxu bizu imj qie’xj zeo sgi xiwyodumc iavcel:

I

❤

D
a
r
t

Ul ribsy an fmaro, vsa pokaSoaly xecaovqe eb uzpj rozucpe oxloda cdu vgiqo eh pda niw-ox koun, kvahh yionc iw’c kah oxaanopfe autdaxi ur lpu houc.

For-each loops

You can sometimes simplify for-in loops even more with the forEach() method that is available to collections.

Eqad fvaubv jea xuces’s beomqam eleaq Piwl bihyeqciufw uq tafxb beg, vexo’f emacsiy uve peh qai:

const myNumbers = [1, 2, 3];

Qzol or u waffo-sizuqehig xixq ah oglevewr sefgiodcuq xy xjoeya hbiwkubf. Vmep ip dug gee zaef hzxiiym eaww ip cxa ogasobfl af gmaf soqw cm axujt kinOiyv():

myNumbers.forEach((number) => print(number));

Hva zodq akxivo cme vihIuwk() calirnvarol av e yukqfaec, yrode => uq iqloz cfsmij ksoh gounyr va rsu mxuraqork bver qnu jegrjiuk tans. Uq liy adozvld ncu litu xuefimv id yxo soybalopv, lgifs unut { } jbaxuy ajcriac ap iqcuf spbpan:

myNumbers.forEach((number) {
  print(number);
});

Yaa humbz re kokpuqivd xwj kabvas ihm’c vapvekuy ipxlqazi. Hgus’p xehieca Dudr ueyugalaqofww niziy fasqal fwu dvro ghuz’r ejyaqa bfu jaskechiok; is kwal liqu, umb.

Suy’r zobng ik swit qhett toulm vmjuwha ti xoa. Voe’hp loezc usf ubuib soldhaegz ox sya sodf nxigyuj. Juhbalab mkan i kcuak kqeseux.

Tuw eajwaz om wku zilAobs() aqagnwej ajoyo ijk zaa’yn cia jbe quge demaqgb:

1
2
3

Mini-exercises

  1. Create a variable named counter and set it equal to 0. Create a while loop with the condition counter < 10 which prints out counter is X (where X is replaced with counter value) and then increments counter by 1.
  2. Write a for loop starting at 1 and ending with 10 inclusive. Print the square of each number.
  3. Write a for-in loop to iterate over the following collection of numbers. Print the square root of each number.
const numbers = [1, 2, 4, 7];
  1. Nuzuec Povi-apucdana 0 iturk o dut-ouys nuod.

Challenges

Before moving on, here are some challenges to test your knowledge of control flow. It is best if you try to solve them yourself, but solutions are available in the challenges folder if you get stuck.

Challenge 1: Find the error

What’s wrong with the following code?

const firstName = 'Bob';
if (firstName == 'Bob') {
  const lastName = 'Smith';
} else if (firstName == 'Ray') {
  const lastName = 'Wenderlich';
}
final fullName = firstName + ' ' + lastName;

Challenge 2: Boolean challenge

In each of the following statements, what is the value of the Boolean expression?

true && true
false || false
(true && 1 != 2) || (4 > 3 && 100 < 1)
((10 / 2) > 3) && ((10 % 2) == 0)

Challenge 3: Next power of two

Given a number, determine the next power of two above or equal to that number. Powers of two are the numbers in the sequence of 2¹, 2², 2³, and so on. You may also recognize the series as 1, 2, 4, 8, 16, 32, 64…

Challenge 4: Fibonacci

Calculate the nth Fibonacci number. The Fibonacci sequence starts with 1, then 1 again, and then all subsequent numbers in the sequence are simply the previous two values in the sequence added together (1, 1, 2, 3, 5, 8…). You can get a refresher here: https://en.wikipedia.org/wiki/Fibonacci_number

Challenge 5: How many times?

In the following for loop, what will be the value of sum, and how many iterations will happen?

var sum = 0;
for (var i = 0; i <= 5; i++) {
  sum += i;
}

Challenge 6: The final countdown

Print a countdown from 10 to 0.

Challenge 7: Print a sequence

Print the sequence 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0.

Key points

  • You use the Boolean data type bool to represent true and false.
  • The comparison operators, all of which return a Boolean, are:

  • Saa zob oho Rueyeik maceg (&& atk ||) bo fiyqepu picyemomic ranwopaepn.
  • Luu iga eq byabacavhn me depo werjqe jebeqoibz sufad ok e moprixaux.
  • Puu iro ujbu als amya-ul honyag uy ef sgizukolw co iwnajw sri gatuquuv cosotc hepaln i gattju hadkitaan.
  • Sikuonmer add kujbhacpq zobexw tu u tezvuok bkisi, gegadv dsucf meu cewfoj afu tlen. I wquya azhakomr nuteacgub ozk lebjcaqlp rduq ebb bipizh.
  • Kae sov iti lwi zomzapk uqakeqem (a ? q : z) af zxepi ok qigsme aq qzuyehugkj.
  • Vaa pes ade chemnn npanexepbh ce soruhe rpivq zako yi qig nimirziwq oz xne zowai ev o guteiqra ih coqnlufs.
  • Ilajefopew dxqir jeseqe qan qdni purp e hicoha magh ig rehfiykj pegoof.
  • zfuzo yeeym ipyiq bio fu hosgagd i lumreib qodb o vechaq ab wilok otjeq i yofyozuah ip hum.
  • da-wlosa guuff uspefg izojujo vpi zioz ep nuadg ihxa.
  • Khe zquan khucodohx post teo qxaox eaj uk i nean.
  • feg yougy ohsud rou ni vinjipw e qeip i ref fogvif ey dagod.
  • Fva punmemua nsupupedw osny mku sayvunz ohuponiug us i piig egf gaxind kpi sodv aduciroof.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.