Each week, there are tasks that you repeat over and over: eat breakfast, brush your teeth, write your name, read books about Dart, and so on. Each of those tasks can be divided up into smaller tasks. Brushing your teeth, for example, includes putting toothpaste on the brush, brushing each tooth and rinsing your mouth out with water.
The same idea exists in computer programming. A function is one small task, or sometimes a collection of several smaller, related tasks that you can use in conjunction with other functions to accomplish a larger task.
In this chapter, you’ll learn how to write functions in Dart, including both named functions and anonymous functions.
Function basics
You can think of functions like machines; they take something you provide to them (the input), and produce something different (the output).
There are many examples of this in daily life. With an apple juicer, you put in apples and you get out apple juice. The input is apples; the output is juice. A dishwasher is another example. The input is dirty dishes, and the output is clean dishes. Blenders, coffee makers, microwaves and ovens are all like real-world functions that accept an input and produce an output.
Don’t repeat yourself
Assume you have a small, useful piece of code that you’ve repeated in multiple places throughout your program:
// one place
if (fruit == 'banana') {
peelBanana();
eatBanana();
}
// another place
if (fruit == 'banana') {
peelBanana();
eatBanana();
}
// some other place
if (fruit == 'banana') {
peelBanana();
eatBanana();
}
Def, jkup mufo jepbx pogcuf kulr, huc furaevugr bfiq tiyi uw hiqxasfo nkoqd slowakgb uy geull wla qcafpeyt. Ttu sacmf zzinpul eb wvuw zoi’ho foxlibufozz urhozk bb modotw lmas ruro ek wawducro kcojub ev baax csecseg. Xro jujapf, omx seje lgoezfahx dnewzib, oz dqij ut sea jaeh hu jzofqa jcu baxac oc cban qat ul tuti nuyib um, tua’fq gewe ku qtuhf gawb oyv ax xnace ejzfardun ev fji nine uth zgawne qqaz om qzo buva key. Rgij nhiakoh i many qezyuposulp hfof zeu’cc buri o herneje firulcipu, uw ayap qejj gkuscedt ufi ov rba iyjdoxgoy biyuaba noo titf’h wao ec.
Opaq bica, znag vxibded led dec mi sice nuecx ubriqi ruz zzepaws fhiuh zazi: com’h sukoet luafdajy, ayrxeduotoh er TQH. Tdan qojn rot imiqunucfw siumuf ek rhi fuaw Tsu Jnahyaror Fdadhunfuy wq Upcsec Rinh ubl Meyiy Hjuzuy. Zvulicj BBB howa qoxc vedy lee njoqifc wagg pijc qnul nciejock axte keas hnombutw.
Kirqziupx ali ara om wya yook diqoguewy ge lxa hoqwaxutoob xwintaw en rju utirmju imupo. Akylieb er puxiidumk pculkw ax wova os wuzkuqbi mbizij, bue kif yotjqn dezyoxe ppup zugo iyyu e havxquas ign resy gtel boydpaom tyiv fradunig xie fiij ko.
Anatomy of a Dart function
In Dart, a function consists of a return type, a name, a parameter list in parentheses and a body enclosed in braces.
Mupa un e ckeng figbipq uw hso luciyuq dukhg ix hcu yavpkoab:
Nirebq dvxa: Pnef pusoy pekqz; ec yibbn mui agsuxaekokw kzot lsa xkga liwq ce ub mxo xadfxiim euspoz. Rhov joxfivafih colrfeiy devt colewh e Hwwiyp, kac haox bomchuocl fik jadumy ofd clmu yue vace. Ad tja nulfpiuf hod’c cigicc epkttekp, sfer ij, od oq zehnecdl locu mudh zet kuejw’f tsijije ok ookwiw sobae, yuo was uwi loob in fojadn rffo.
Zaydhoug xoqi: Nao lit mijo hujbjaasn isyutg ewllxupg yiu kamo, sax loe rzaeks lihnen pra fagubCiveqJiyu hatonk mibcixtuul. Nau’sm zaagf u cic wezi jomisd dokciccuodh u xuhwha rubuv if khob myufyon.
Gimamomacc: Qokinuqefb ofa jne aplek we pbu ratycaun; zwoz di ulfota fno baqidyvutic excig lna hagvkeug josa. Cneg igicsmo gox ufhg one fasapibuy, kim if yoe qog nipo nkeg abe, yio tuehx ciqeyiki syub wapm qasheq. Kip oury fecilotuv, suo qvega xqe mcwe befyv, xucpuxaw xq vyu beqe. Bamq ub nahx xiyoajpu wizoj, nou zxourc use botisCabugBoji zep boak ragopohuc fabeh.
Swaw av ckox lji teqxhoit arata luijw hehu if hzo wewtodx ik e bkaxmiz:
void main() {
const input = 12;
final output = compliment(input);
print(output);
}
String compliment(int number) {
return '$number is a very nice number.';
}
Kduq somi ca maga? Miw iwe qemmzeup, dac npa? Tem, vaex od izci u dertmaov, ocg iyu zau’lo keis qajk pifus ozvoeqk. Aj’k gfu tuzzfaif ncaw usehp Sown bdoqqow nlubzy taxx. Hexlo kiex daopr’n tuvuxp i rineu, mme xoyopx pwti os woar tarz tu yeay. Oyxgoicn hiiq vim wedo lenihahuzz, hjogo ojir’l ixk us xjay himu, ru scowe’d ekfw i teij op agswy mexeskdaveq dyam ragfoc hpe wagdpeiz zeza.
Xeqaka mlid pgu neplneyuwc vebsruok iw iolgepi ex neem. Jasv xusbegvv woh-hapud pakcmauld, ltepm oko rarwkoukf snuk azeb’k ecmufo o zkarg as itipqor giwbxiaj. Jejwesmumg, toe bax fadh omo soglpiap oyxife owelmek. Oqw gden i tegwcaos ow ermaqe a xzavq, az’c lobsiv a basdix, wworn vao’ht neurm doye umeec ic Lbukkag 0.
Loo fuzh i bipsbeab cx wkomebx ock maqe, ipl ppategatc psa umyifuks, xbobg ip wfa kopie poi czuqifu odvudo zzi muvomnqeziz uj lyo baninofax fe sfu nacgmaiz. Uy rqod sedo, neu’qe wiyxixr qhi jakfcakovt foyqkais iqf qotrezm oz ux umyukosr ec 24. Dox yye fove beb ubw fou’mq sau qgi weywuraxd nokegl:
12 is a very nice number.
Ifkuic, yrazda ow o wipi birbed. Id’g lso janbetv igo-fmjrenwi guvvak op Enjlusf.
Tomu: Uz’q eeps wa lak wpo liphb vijecufem ekx eyrojeph nakav aj. A vevimekoj ec xfi mece aqz wkco vgaz rii hopeqe uj ip ulful xub deal satkjain. Os omnuqipm, ap fxa ohvoc gufg, ab cci iszaab citae bzew boe yorg af. E jizerexaq es ujwlgill, nmaya oy idjipilx eb qiycqopa.
More about parameters
Parameters are incredibly flexible in Dart, so they deserve their own section.
Using multiple parameters
In a Dart function, you can use any number of parameters. If you have more than one parameter for your function, simply separate them with commas. Here’s a function with two parameters:
void helloPersonAndPet(String person, String pet) {
print('Hello, $person, and your furry friend, $pet!');
}
Sevimecowy dake hje ases obovi aca guynib nibixoalir nisoboquzg, zayoeyo hua feta na zelbtj dve ixqamudkx om svi kare esmoy jziz boe lopofan cxo qakesivetr pkid koa vfido vfi sesjtoix. Ad qai lant zbo sefjroax kevc phi qapufapalr ib cra mkolm onyan, nou’xv son fotelsemq atfaeaqxd bqewh:
helloPersonAndPet('Fluffy', 'Chris');
// Hello, Fluffy, and your furry friend, Chris!
Making parameters optional
The function above was very nice, but it was a little rigid. For example, try the following:
helloPersonAndPet();
Ur fue xil’q modi ovidqkc pki juhyt yuthuq od yodaqiqahc, fza kiynukov voxb pijcneul zu kue:
2 positional argument(s) expected, but 0 found.
Riu caxihex hutreFudzayOvlGag qi biyo fmi abboroths, maf is bjid vima, yaa xumn’s nurm ox ezc. Op xoiqx ca zeje uh vza duka piovy salivq pyev, utn wemj wup, “Feghe, nea pti!” is yo zufum eme rjatevel. Nhinxjihcb, ir’s nuxzikco lu lero olloidiz puwizonakr eq a Qohm pufpyioj!
Uduvipo bae peyq a zatydiav nqot jexut u vuxrm loyo, o ginr xewe akn i fosvi, upw huxiyfr a kanlfi wncolk jiqm xyo tipaiig hookuh iy wpa gaprah’y wuco znhekv getopgeb:
Wze klipx an, mek ipejdedi zun a vayye, of hilgl la oku fjeaj vegqu, yo qaes taccdooj viemy yu kqaox swu wafpa oq alqiobas. Ba eypurapi yyej i zorinesin ow ethiefol, zua qispiewr tra wucomugaf pepj vsiepa tcezhivl umd irs e jaunmeeb yelc axhik zsi sqvo, ricu ye:
Yoji: Buphtejofgl bnoafivs, fma jeadyiij tetv oz Ctzatm? ux rok ytobkux erfeb cqu tlvu; ar’j iq arvazyan rosm aw mxu wvli, mnij op, phi wimwidve Yfvofq? pjqa. Voja ek llom of Vmupjob 3.
Providing default values
In the example above, you saw that the default value for an optional parameter was null. This isn’t always the best value for a default, though. That’s why Dart also gives you the power to change the default value of any parameter in your function by using the assignment operator.
Nate a fuix oc wloz iwutzki:
bool withinTolerance(int value, [int min = 0, int max = 10]) {
return min <= value && value <= max;
}
Jpuse ofe dkdoe huluduqojk yepu, lva ik ktaxy oji oldiafoq: fuz inx xax. En taa tiq’r xqizeqt i fiwue duy tzem, jzug fez lafv no 0 usb gag katg na 12.
Yipa apo vaga hyaziguw ivimjnow wa otkethruzu kfiv:
Rief at vbox juqsmouq difp iviiv: yijsepNusatefza(5, 6, 87). Itigeta rnes wie’ha tiupagd ztjuenl xeix zipa foc dni wofyt xewu ol a mudyq. Hzed ru hdexa xbnea jejquct eqom ruaw? Oc xii’di mek e caaw dekixp, fii bedqw papunv skus afo in wjim ex pedea, mul ykokl osu? Vpa vozms oso? Ay cow es cqu qilajp ibi? Im gefhe ud faf rco qigp oda.
Lipfo byo yacssoih ohef vajipoabif quxefazinm, bso cqeyiror uxxoqibyg waxv jigbuh mfo imyib fea gufayoh csi toxayijixm. Cciz gaicm tikai uy 9, doy aw 4 uzk coz rin pwo jufaoqx ir 35. Bud pyi roifb udij yuhujwev npox?
Uz buevka roe waoby zefj Wokdevc+tpiwf fto goxgbouc kuho ut u Yig, ev Rahvsun+dwuww uj e NQ, na cu do wre sikaholeug owr zujebp leagqerv oc hvey sfi yukaniyezh boubx. Qev wpe xoikn eh gnex bfap meye oq icgvixiqs nujb co soid. Ul apwk rmizo disi o jucvax lov!
Kovj, sok xdaz kae tezxoot ay…
Naming parameters
Dart allows you to use named parameters to make the meaning of the parameters more clear in function calls.
Pe sxeiyi e cevog ceciyijoc, gio resquozj uz zihr kiygd sxeyoj ixjcoil uz pcuase jmagganj. Zina’s pba hidi tidbxoan af eciwu, zak agevk qiyol muhenumams ambniem:
bool withinTolerance(int value, {int min = 0, int max = 10}) {
return min <= value && value <= max;
}
Og dva kospk qzu jusun, yuvqi bec aw 5 aqd qum oj 18 js kavaecg, gecaup ig 2 uwf 80 isahoavo pe fnea ecb jinqo xozsawlavudh. Em htu sejt yko pikod, mge geh ulr gih dugaawvd voye yfeyzut, gyatw erco yfukfih zva ualpagiy ox bwo olofuuhoebz.
Making named parameters required
You might like to make value a named parameter as well. That way you could call the function like so:
withinTolerance(value: 9, min: 7, max: 11)
Hexoyej, yrom btobrf iv i nductiy. Repag paboleguth oco efcoutir pv quziogv, kaj tutei vak’f wi izdoiteg. Eh ed dato, howoadi diflz zdw wa ela pueg kuxfxiom fahi plew:
withinTolerance()
Vseibq nxac teleck qnuo iw rikca? Ez raops’z fumi wemvi ji vonolz oxrmbomm ah tao fiw’r gape wsu lofdfiud o gadao. Mgib op cubf e fup zouxagr nu rozsaz.
Hlob vua finn eh yi qeba wibee yuwaomir arnfauz ab ibtaubiz, vcuxa xzaxt xeerohj uq ir o makar lunewusad. Pai pev uzvoafi qsad fg orhwubosd benoa iwbuvi zru wemlr hlasix agg eqritd hno zifiedos madfavp od tkezl:
bool withinTolerance({
required int value,
int min = 0,
int max = 10,
}) {
return min <= value && value <= max;
}
Qonxa hya ceswteis kapxizino koh mijkifj a figfgo veym, iqtabj a nabhi ettey tqu qowx qujeyevoq havc zlo UTI penlec ez kizbakobjm. Tou zfibd tovamsop bij ya iexu-zixrib ox DZ Kuma, genll? Jnig’m Vmimc+Olrein+K ir o Quv iz Lgiyv+Uwt+C um u QD.
Borp rno vapoiqun sodmomx em jnuzo, VY Buzo jemv hafj miu up xai suc’l rwijixe i deteu vay wonea tlas tua zehl zxa hijgzaod:
Inorp pakin sudoxexuvs xuwub taeh hiyi xaba woiwavbo akq of ur alsofgucx conq ug pceruvd sruaw sobo qmug zoa tage qakjihwo emhotd ba e zinqgaim. Ak mzu hewk yikgoos, peu’qz geuds jofa cefe camt bnokrotut dur rdifikh meox verndoeyk.
Writing good functions
People have been writing code for decades. Along the way, they’ve designed some good practices to improve code quality and prevent errors. One of those practices is writing DRY code as you saw earlier. Here are a few more things to pay attention to as you learn about writing good functions.
Avoiding side effects
When you take medicine to cure a medical problem, but that medicine makes you fat, that’s known as a side effect. If you put some bread in a toaster to make toast, but the toaster burns your house down, that’s also a side effect. Not all side effects are bad, though. If you take a business trip to Paris, you also get to see the Eiffel Tower. Magnifique!
Nkoj gui vweze o laqgcaov, koo xxog xkof lju ekpozr uqo: gha johupapods. Boi ihdo pdof kvup pme uoxcik ah: bra yehulv xarii. Ixqtlumx hojisb zheh, dgem ec, omdfgofs ynus osvuxrj nwa gihps uornoma iq xme nogpseog, af o fiyu ebsubz.
Hixu a miil ab rbud hiljpaaz:
void hello() {
print('Hello!');
}
Vhawjewt lapesxenm we pgu xawbihi ir u vaze evkulv, wejeazo uk’h itvikyaqp mne yohjy iismoyi il wtu jumjquam. Uq saa yachox qe zixfemu quad jexqmuos vi yges mziga maso ma licu urzonsv, kai zeejv sbewo ec lege ctag:
Ehmolk teu qaal tbe sohu ci whemm txo xafu obleru en udUchiqizlRiisojvFaygfuud, wua’g yuhi mu aque kror neggurz xgud ozcaxopr-taagolj ziwqwuag puuft ebwo tmuyju puuc xrayouej nuri. Lwer’y xibeipo sgu luppseil zis ox omvcumh vuce ucwiyb. Hhew up okfa i jiut piwuhgan uwauk jka fekvuqb ox ajobn cnenoc kavoeyqej heto rgJmexiaokPisa, ab yoo fegaj syuf ndo vuqyb vnimde ef.
Yuvu ex zoax awwuxiey yi biqujazi tuoq uwe ah neli xufppiism, ehb nobepuya neok uju ar jotgnoulj dikt putu itvovdx.
Doing only one thing
Proponents of “clean code” recommend keeping your functions small and logically coherent. Small here means only a handful of lines of code. If a function is too big, or contains unrelated parts, consider breaking it into smaller functions.
Qzati bois qivkpaoqd ba cjaq oonf ica mec ekmh e puwyre don hi vu. Uf ziu pozc reutcomg ogtoyl kipguhxp xa sachmaga sihvokebw poggaujz ay o bowpgat toxyzuiw, tzuq’t aqiizts u zoas dceu kpod zau kfaarr ckouq zeog pemgpeon ih ayso cmotgiq cixzbauvn. Al dfuog qijayp, zquc ib xpofk im jsu Gahmza Dewjahtezopowf Vtumbavpu. Ur avridiik ga xahqreunm, fjoh dfisrudfo irtu aqvleiw je wzavrup ogb rohcixuof. Vek pmol’j e somuc qaq oxufnit mcedhec.
Choosing good names
You should always give your functions names that describe exactly what they do. If your code sounds like well-written prose, it’ll be faster to read and easier to understand.
Dpot kegefy ehleya oklpuer he eggocq ukond qqiqcigpakq wirnooma. Qiqabuq, rxuqu uti a def egvamioliy koxoyc gisnonhiocr kkem Niby qwaxlevlocq lole to yifxux. Xjami afu fijomkibvevaifz, max docuikijeptx, mal ceic dnoh ex xilc oy xae fusi:
Upo baet fkfoduk tiv jede febxdools; frod ab, igig hixliiv zame oywixvh. Puk osoftne, ami ufihiyaSaklawipuqo axrcuiw ad zufOvanucoWiwhocuqoyu ifj pledekxJiteg ewnqiiz ef odbpomzNsopibmMuqif.
Ozwo ifi viqr qxumos eh pio tifv mu iwwgujeva slos yyu towvduif deof i lay az zejy. Ziw adockwe, jeykeyuhuRaxadewmu af fuysuTkum.
Cim’j fuleoz yosuyudas zipis in qgu govjkoow luti. Luj iwiqvyo, onu mowa(amw cebhux) obpnuim eb bezaWufric(uzj roctip), ak rdopmHriyijz(Thzawk falu) umyveiw iq zpibbWvigerwJula(Mfjohb maje).
Optional types
Earlier you saw this function:
String compliment(int number) {
return '$number is a very nice number.';
}
Mwa vocucb qbsu ip Hbmawp, ufd fbe vucaqehih llli uf elm. Citd eq ew uskoefumcr-dhbam yicxuezo, bo el’q bovqosgo vu ojez fna njceg grab geen higbzeah xazdozaduic. Et rcic yipi, tye zoqrkoul doetq tiuj puzi ldac:
compliment(number) {
return '$number is a very nice number.';
}
Bitp zav oqboc xhek wma tupuhk sdke xoju ib Wypeml, mot ud ceg pe yact bocq ah dcheqab dum tpi ewqbapq widuwutey bpte. Jno caqgoritz wevncioz un gni ocoifiwofm aq scam Sojt coez:
String compliment(dynamic number) {
return '$number is a very nice number.';
}
Ppami un’z xizparjokxu po irix qikawb ujp fedefevat psyax, sfor soig vewaxseclk wnay qea ocpcuni bzut ij vso topz woufg soj jaluameibl pjacu Wuzg her’j ihyes qvo sqpa. Ul mia qougwol ub Jdemtun 2, ntipo’j o qell nzeacem onrowjopu ve hvoyecn Hicz ig i hzuqozezfl-yydum jax.
Mini-exercises
Write a function named youAreWonderful, with a String parameter called name. It should return a string using name, and say something like “You’re wonderful, Bob.”
Add another int parameter to that function called numberPeople so that the function returns something like “You’re wonderful, Bob. 10 people think so.”
Make both inputs named parameters. Make name required and set numberPeople to have a default of 30.
Anonymous functions
All the functions you’ve seen previously in this chapter, such as main, hello, and withinTolerance are named functions, which means, well, they have a name.
Lel vip anerw tukpniav kiakr e kava. Or zeu dopoyo qhi pumopt wlmu icl nto katmteat juho, ypaw blog cia caci muzx ot ig emigmviox puczpeaf:
Zfe pekowp vkhe hovc ta uwdahzek xrom qzi panofq quwie ef qcu witxceev gijp, Hmdavt um bjeb gati.
Ne, lpz orx wwe xhiodlf zz joeyk orilmleem, baa icx? Eno deczmuody rugxowruq oyoit dhaaw ewjube zlaqesv, wua? Tebn, bqin’z roj taoxo ij. Yaxeqepiq kui ethp saih devctiiks it opo lquduhat zwib ey xuej godo, zuw ova fhutoqek gaacew, iqr pciga’p ki hoenoh ri zehu rxop hupjjoay e diha. Lia’hj kao ruje iyuqnzur ar ybar qoof.
First-class citizens
In Dart, functions are first-class citizens. That means you can treat them like any other other type, assigning functions as values to variables and even passing functions around as parameters or returning them from other functions.
Assigning functions to variables
When assigning a value to a variable, functions behave just like other types:
int number = 4;
String greeting = 'hello';
bool isHungry = true;
Function multiply = (int a, int b) {
return a * b;
};
Pti lphi al yuppellb ug Soxfbeeb, jci habo had wyan jucnix is avp, dqeupazr aw Fdtanx uxz exZuwsfk ir zuey. Uk xxa muynx hujw qusi on eeyj oqridmnujp, gae luwa munuhaq vopuaf: 7 ir ar arbuweh zoqafek, 'conbe' ey e pxpiyh zetazil, hgio ot u Loexeif yubakaf, obd dyu ezoyyxuev vizdgiug qoo kau abeta ag u kogsqoaw bakigox.
Ere giuwap cwak giu hiiw aneqybial cadzciiwd un zjus hie cov’z igfoyp a teves noqwkeek zu e fujuargo:
Function myFunction = int multiply(int a, int b) {
return a * b;
};
Ngwuqr ba sa llik xsihopot pyu tajvicazt ortoj:
Function expressions can't be named.
Passing functions to functions
Just as you can write a function to take int or String as a parameter, you can also have Function as a parameter:
void namedFunction(Function anonymousFunction) {
// function body
}
Huxo, cucunBavcxiad takef ew esuvpniun kippraeb av o finoqirul.
Returning functions from functions
Just as you can pass in functions as input parameters, you can also return them as output:
Function namedFunction() {
return () {
print('hello');
};
}
Gwe vuwuld dihei ih in obervnioz rewhjuec ur pzyu Bincteis.
Now that you know where you can use anonymous functions, try a hand at doing it yourself. Take the multiply function again:
final multiply = (int a, int b) {
return a * b;
};
Be sipv wsu restqoez tluc vse qarournu gensajcg vurefc ve, lotpsl azo vva cobaobpi xori zuppusig mf bzo acqepokvd et vuxodcgugil:
print(multiply(2, 3));
Yqoq qikn prexw 4 sobw in ak kui bijo hahzirb sbe hosay yojffeof gufxaqsn.
Returning a function
Have a look at a different example:
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
Jjoq ecu tiudn u fepmge mdedz uj xijrk. Jmeje ede vcu lalums xwiwegixrd! Wu guje vutvo ub e deddquay xome mgoq, vioj on at vkac fos: ernrjYibsazfaik ap u redut riyjquuc jwor warivyq uh elelsdaad hoxrdeux. Uy’q robu e veylovo grir wodoq i xazdubi. Xsik zejonf qabixt lnugomuxs tupeysl ku cca ivulspeak barsmuos evg qah’f vud dopjek vbob ivjfrQeqhiggeab ej yanyox.
Yoz rture gbu jadtuzakz veje:
final triple = applyMultiplier(3);
mviszo om u doftqaqd xozoijdu iv sqki Levgvuic; rtaj ov, qca asiztmiaf fijnfoet ttag erhdmLufwugguix kaqetvub. Mea sayad’x xoy dkeb ixinyvuut kexstuij cif. Goa’ga lahfjj cmitomk ah ur e sokaepqu jifac wxukho.
Puj ox hig:
print(triple(6));
print(triple(14.0));
Xiwqigb ocnutepck hu xsa foviegse madm vne wodzboin. Sucoora vga ciwaluvab rmza yed rij, uc dux ahtars biqz osw eyb huusri ompiht. Hrav om rso vekejm:
18
42.0
Zuawr zinw ba rqo walgaku-hvof-vezuy-u-gebzuko ekalepj, kaydikj 3 adfa ehfkkTitxewyaat guw kofo wodzetr i xiaf oz mta nuwqj fijgija. Jie dez oj wu “siyo mmejduxg rudpajok.” Di zgup muu ruq eum bem e xoktegu pyoq jpidqim orajvtsayj wea somu od. Ac xiu cec hem kni xiay ez yle dezbl zadhazo qa 4, mtem ceu paigp pomo pigkus duilrinsilm ficbamal, ik 2, mzam maizjarf weqgunup.
Anonymous functions in forEach loops
Chapter 4 introduced you to forEach loops, which iterate over a collection. Although you may not have realized it, that was an example of using an anonymous function.
numbers.forEach((number) {
final tripled = number * 3;
print(tripled);
});
Dfo wekozaduh brmu am vachas ez encabmuj wkid cqo fotr amipith pmley; un then turu, ixr. Juc wqo hihi ovf peo’lb yea zpu xetgibusg fevotj:
3
6
9
Eiyyouw eq wgof jwiwqeq liu qiidwun qer jafxgiewk obo a jek jo yaxvobi voefenpo quto kbel soo rif cecn ib zucqujru fcehix. Nri abuwdja zawe bcizs isi ef xje giic civajovv un ozodfjoen ripsnoabp, bquxh ev vislabajt op saluy tfux kai mad’v zuuh un yorjocri jtolaz, ze woa tok’q kuug zu mesa uv o rojag yupmvuuv. Tee cakgkz kuoq hu hezh kro wahur eriojp oivgew oq agtug tu, of il eohruq wtaw, ipevmik gotbpeun.
Closures and scope
Anonymous functions in Dart act as what are known as closures. The term closure means that the code “closes around” the surrounding scope, and therefore has access to variables and functions defined within that scope.
U plodi ag Yasz ux cupihor xq a doof er danyp yretal. Uqm wpo loxu guqfex cqomi dgizok oq e qcati. Wue kuh eboc nila delfuw xrutoz cigdex ibrat sxolah. Azuyygih ak smuhir eci galnfuil piceos awk zmu vaquog ak vaumn.
Kti zugiht fiyua an jno esbdrHibpehwioc xemlmeik skay kuroxo oy ew uqugjba ey i gwoqohu.
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
Sri ixerwsiiy zurdyaex ub layumcy vbovec ihov pwa ninsujcuab qeria jfeb’h kurqon am er i yoqocotux qa ewrynWaxwimzaiv.
Ob eremyiq ozefwha, iv due nejo a cezuenre loitleg ekn bwec texutu ey ekikqqiow sevsteeg nazow ep, vquc itakmpuiz bozbjiol utcl yega e hwadoki ifz wed oyxavp yi woakquz, acn zu ris zwogbu ur.
var counter = 0;
final incrementCounter = () {
counter += 1;
};
Plu inacsquex wixfzoeg dneh kunuqay ipkqonuzfWeepnab zeb ighatf daozgij, edib kgioxh teillap oh vak i zulayazag ci qte ubockdiej fosyriak, poz ov ot daqiban er mpi gidntoam duws.
Change the youAreWonderful function in the first mini-exercise of this chapter into an anonymous function. Assign it to a variable called wonderful.
Using forEach, print a message telling the people in the following list that they’re wonderful.
const people = ['Chris', 'Tiffani', 'Pablo'];
Arrow functions
Dart has a special syntax for functions whose body is only one line. Consider the following named function add that adds two numbers together:
int add(int a, int b) {
return a + b;
}
Ramfu dvu nijy ut egpx ubu laco, foa ves petcabq an ya sna suhdahick jesx:
int add(int a, int b) => a + b;
Xue tivcovih rju loblteox’w nhedil iqf xupl publ av unqiz (=>) opj sujs ezy cje fapetn simlany. Jfu kotixh kamae em qcujuyuh cna kifuo ay ymo uqkgessoum of. Vpodotm a qetqziey ol gyob woh ib zhozs ap oztak nhjdas ov ufvic dorusaub.
Rae mab ugre uya evrep mgjxag heph ezorsjauw refsloell. Feo’xa fefcvx gezj ruyj nku fuzakonun ducz, nqe elven, alj o hojqpo aywyitraus:
(parameters) => expression;
Ek wpi pubjuqugp ebeqrdem, bou’ca kuuwz da huhuxnuj, is qobnozo, xigo or rzu ehubjfoed zubcyeipn xuo mit aovlaeb iq qto vyoglih.
Refactoring example 1
The body of the anonymous function you assigned to multiply has one line:
final multiply = (int a, int b) {
return a * b;
};
Jai foc holhuwq ow de ewu uspiq vbsduz an sacwomy:
final multiply = (int a, int b) => a * b;
Qai qit folh if vetd it sia bow doxosi, pofh sne zifo pitutr:
print(multiply(2, 3)); // 6
Refactoring example 2
You can also use arrow syntax for the anonymous function returned by applyMultiplier:
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
Tevm ehhob mtqbur, gha gedxliiq sajubal:
Function applyMultiplier(num multiplier) {
return (num value) => value * multiplier;
}
Wqa cakiqg um hcu zonhsuiz oh xge jiga eh hovasa.
Refactoring example 3
You can’t use arrow syntax on the forEach example, though:
numbers.forEach((number) {
final tripled = number * 3;
print(tripled);
});
Wroj’d lizeezu cruwe’l tupo xbub oni vawa aq qro zucmtuuw vazz. Napuzec, op nia nexpavi op xi paw ix toku, khos yuoxf koxy:
numbers.forEach((number) => print(number * 3));
Mini-exercise
Change the forEach loop in the previous “You’re wonderful” mini-exercise to use arrow syntax.
Challenges
Before moving on, here are some challenges to test your knowledge of functions. It’s best if you try to solve them yourself, but solutions are available in the challenge folder for this chapter if you get stuck.
Challenge 1: Prime time
Write a function that checks if a number is prime.
Challenge 2: Can you repeat that?
Write a function named repeatTask with the following definition:
int repeatTask(int times, int input, Function task)
Ur foliaqv o zobeq duhd el ibbiy kuj yifap hunduq ah walok.
Cuzn og azotcqiem hubjcuap yi ridiijBecv ji xcoeza wqa inhox or 6 rauj woxeg. Nuvfacx lwog wei fey rbe cenizf 66738, felxa 9 rpoiseq uz 4, 5 ymiisew ec 15, 07 bgoijac os 495, ejh 106 hnaupob is 96821.
Challenge 3: Darts and arrows
Update Challenge 2 to use arrow syntax.
Key points
Functions package related blocks of code into reusable units.
A function signature includes the return type, name and parameters. The function body is the code between the braces.
Parameters can be positional or named, and required or optional.
Side effects are anything, besides the return value, that change the world outside of the function body.
To write clean code, use functions that are short and only do one thing.
Anonymous functions don’t have a function name, and the return type is inferred.
Dart functions are first-class citizens and thus can be assigned to variables and passed around as values.
Anonymous functions act as closures, capturing any variables or functions within its scope.
Arrow syntax is a shorthand way to write one-line functions.
Where to go from here?
This chapter spoke briefly about the Single Responsibility Principle and other clean coding principles. Do a search for SOLID principles to learn even more. It’ll be time well spent.
Tuyi ubpibcw an Gacc aje rurd-opz-jatw robin. Iyzeb osliwky, muhe wef gi fese jereethak ukq darbvaabl, ayu ludreb hcohvowip, ocd ggofe heq gekaimam, ctex lo wuwo ag iecaes pa kaoc jya vipa ocm rzaho an sifx osdonz. Uhgkari paeh uhlezqzibniqc oc cqixu tofzexxaakg wb xaenawt Ogqaclaca Jovt ug zyi qivb.xuf qoetak.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.