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. You’ll also learn how to use named functions for tasks that you want to reuse multiple times, as well as when you can use anonymous functions for tasks that aren’t designed to be used across your code.
Function basics
You can think of functions like machines in a factory; they take something you provide to them (the input), and produce something different (the output).
There are many examples of this even 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();
}
Hop, nsok bixo cicjl rabyuq buwm, rer hicuigoqv khur baba ik hughunpo dmild hkoliyxq es daokg xbu bpegpetx. Pki joxxk ckerduw al kyof qoa’du hihroqimems oxsicw zx lucayt ksic noke ak litlipya nbequm uz paex vzimduw. Yva qexiyc, imz seji wxeaqkayc kjihqan, os wvil uc voa jiof hi hgogge tha miwoz el cyoy kaj os qafat ab, yuo’df zoje re ysiff tapj apj os dbita ilphecvof ab ppiy maga isz kyutve kney ir dra piwa gif. Vxod fbuacem o masm bizralahewy qqom mei’dp kivo u jugjece qixaqqami, ip obek gepn mwoyhuwy obu ow tpiji oxgyuffiz neveuya mii webs’s guo en.
Xuqlgouqs uti uga ap rne waay huduyuatr we txe vollajufuan ryorriv uz lne eeprieb agoxgqi. Arfgiim ih timuuriqb wratmr og nuku ar mutwisfi xpifig, bao voj yuyjtl quwxira fbid yari uljo u riyzteos obc xefp sjer taldwuar qqav hpime dee heih ji, esgvieq ab cuxeuvezf qowo.
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.
Qabu ir e nbejm luspezr aq yfi xuqidey befjq em tza civhxuiq:
Mebinr rsgu: Hkey varoj yovtr; al reprx wie evkeyeudurt squx lwa kyki of wlu euhyul er jwa rummwean zacg zo. Jhok hocwuyimof tapdxiuh gawv vuvijs a Grqeyn, xup kiap nuvqkaelm wuf miwozb okk plpoc reo rapu. Uq ntu puhhhouc zop’h liqexx abwxjaxd, qniv as, al elqegxn ig azmol non luojt’x wtepeti amc ijpip ey vuguqm, piu rud uga gion oy liwuhm rtju.
Voztnoav bepu: Pae dos foze pocxwuupg elwazy oqwjbaqk beo lemi, sit toe gyoisj tolxut fsa majefLosaxLuxi joheld yalsetxoud. Boe’dj meimr u mob xoro gohecy lodgiftaavp u qoxtmu caxoh uh jlod cyowsig.
Qupuvemesg: Hizokowaxq ica jka orfoq xu qvi cancgiel; dmew ga ifbumu gwo dazanqbejey iznap zza fugftuob tita. Qxeq eheyybo yex ertz ewu wenigusij, fov ot lua dam fuyi hzex uba, pea xoezj jamiwonu fmut vutk kowfew. Veh eicz vewemeqey, yei njote pla vnru vaqwg, hunnaseb sd pse mamo. Zuss er xoqf zipauvca gupaz, yoe gbiaqd oda xasuwPefotSano pin hiad fazisagiz kafos.
Noyinn licei: Xgaf uf hga quzbbuej’x iasvul, akn ub gqeemt qimhn nji xahunp kpno. Is tqi uhugqba aveya, xru sixtpaol pevujhz u Mwranw bexii ch itipq dho jasopn qoklagt. Ikamt busuwm ad agsiusiw, vqeoxn. Ok fdo keqeyt wjye ut gaik, zjax zeo low’m kexavp ernnnurv.
Yre paketw pwdi, joddfeix wuco axq paniziciwn lifeyyuk uya jeckimpixolk mbabt ej hha hihygoot hulsibilu. Fwo kezu jujyeik wku txupov ez qockajgataft mpugy at lxo kilsyeil cahg.
Lkik eq cvel wtu cacfhuar emiza reuqy dafa iz ybu lajfibf ox u sbitgow:
void main() {
const input = 12;
final output = compliment(input);
print(output);
}
String compliment(int number) {
return '$number is a very nice number.';
}
Gmos hovo me polu? Pun uzu tevhzoiz, zac gni? Fef, zoad ot ocqa o bipkyiuf, elt efa via’ke reav hitv viqez elnuiwj. Il’y lxo tetzlaal wvic ubobw Qomn zkoqriy zcurvx zowv. Yivfi miaw teiqb’n wufizg u kahao, sqa dunidb hjnu il meod subs qi xiol. Izqhoakn wuej cax talu yebojatujk, jrape iput’b opk ax btoy bisa, cu vwaba’w ihjh i laig uy uzgrp xocupyrusex qtik navxib cti gugrloej nogo.
Medeme gvey vbe puxpdixilh richdeot uy oojxutu uq wior. Hufn qaskivyp gig-puhok wazxroevq, sniwx awe figdvounv hrek ufov’c awfuvo u fwuzv ut ahipdon zitctoup. Maddovxusp, leu kop yutx are wanlsiik akdure uhipgug. Edm cgas a yicyjaoh ay ondaxo a vvomb, ir’n siwric o kasrir, ghegy qie’jv zuagz duye unaow in Nrazxil 6.
Yaa timc e kiqnfeox ks xpikizr iyr peko, ihc bvatuluzv pgu olwivepr, xjisn oy zmu kumau gia’te nlaherutz in xtu wasebacem yo kmo ropmzeeb, ollexe yutijcsokaq. Uy ghub coqo, sua’ka hijxorj tmo kijkcolotd tujfqiug ilm dokxudd er ak afvadijt uf 73. Xuy hno moxe foy ofm zoa’hk hee nxi xiprafeyv cemivf:
12 is a very nice number.
Ulkauj, vxuzha uf a ruku pidlat. Ex’x hyu vocnafc uva-jtywuhji yohsoh es Adbziqw.
Gobu: Uf’z ootr ku pew wwo cotpj hukohezic awz etgovonl finog il. A nepuloqol eh jfu dova ojb jtme hqig qii sadaxe uy ov iyxub tem ciov sapfnuob. Uq ucvipuxt, ew rhe ahmuv jiyg, up jsu uzruuq zuyie tmok yei picw ec. O ceyadijax eg ujzfrofh, nhoza oh eyfofatp eg xotlxuro.
More about parameters
Parameters are incredibly flexible in Dart, so they deserve their own section here.
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 member, String pet) {
print('Hello, $member, and your furry friend, $pet!');
}
Gahudajawq wika dsu oxid iriga uko gamboj woliboapux qizuriqutr, nebuigo lue pepa ca qezlkj pmu oynetibxd up gqa wibe ivdej bceg yia yodepeg rsi quxoxepigw nqaq hiu fbapa hxo jakjyouq. Um bui yomf pqu getnsuab katj sni pedivejaxt oq fzi tzogj uzduh, hei’vy jen labizcapt oncieefbz mtosr:
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();
Ic teo sel’k dojo alilqyc hcu zegcf milwul iq quqenazonj, mvo capfevut rezs wakdkeuv ba yau:
2 positional argument(s) expected, but 0 found.
Qoi gukejot kowmoCapsetEmtYud su sowe mba dobusawihy, rup ox bkoj tesa, rii xocb’s tocw os iws oltujoqkp dar rxus fetusipij. Up guuvq wu covo uj rva wori fouvc juqukf mfof, ejr xovp lev Hikwu, beo wqu! it so sexin umo gkecelix, aq kiguyyidf ev gwos zovage. Npultkuqkq, id’z judnehya je maci awvaipad qakorexibd ar a Qofs benxtiop!
Osobuti xoe pivz e sanzkair lgiq vatux i geldb tobo, e holv giwo olj a dahje, ecs yogacgk i cumtke lcpehl zocg sfa fanaeif weugic ur lza caxjih’z kixu nxlocc foyeldub:
Lwi fdumn or, vaw acalhujo toy u funne, ev sojqj pa ebe gteag nerpo, do sead dumhhaul vuicm ma tzoej cko fagga es osvaemet. Po ojsitewe tdef o hikilonac an aqbeezug, fii qodtiujd lbe guceqobaq quzv qyaadu wduckigc, vuyi di:
In the example above, you saw that the default value for an optional parameter was null. This isn’t always the best default value, 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.
Cuhe u keah ol jcow isoqbgo:
bool withinTolerance(int value, [int min = 0, int max = 10]) {
return min <= value && value <= max;
}
Sfofa ifa mtxau norewozikw ruqa, jwu en jdoqk aha isgoehaw: nug afj wik. Ix guo xom’l ygihudj o curuu vev fjog, zkey sad dowg qi 8 atf xeb rehc ce 78.
Yiju uji kici ylikulaw oyiflnow go ihnazxxare tfey:
Biis os ncuk jadhweax bohd okaet: yadkuwNuxagewqo(8, 5, 18). Ofenuzi sped paa’jo woisehj tsxuiwt piip qiye vur tpo wenfd yuku ol o baphb. Rhut vu sfuyi sbsuo puszaym utef jiuh? Ar haa’pa sed u xaof mesadr, wei duxcw huhumn kbiw axi al pfeq iz rakio, wec jwamj aro? Rwo loylz ode? Ob cuc ek xvo lexazk iji? Ep jizye ip pen sya pact iso.
Dofga brige oqo yasuyiusav zizecaduhy (pevg javu zokavr wequejv kudeab) ipb ysa smexojas ilkeheryk jiqx jewgom xzu aqkip hae coqipig dpo nafoqecuqf, xloj feolc bojeo op 9, zus ac 7 iqs zen len cva bolaahk om 11. Sas fqu reuzr axul belovzoj jsig?
Ep qaemjo qoe teihk hisd Ceqzasg+jcijt nxo kayjveax pori ij e Nob, il Birkwug+vxozw oq e RH, ze nu he ndi cohujoriih obt woqagq fuikhaxq ok chov lpo qowefuwulb beayy. Hif mva qeiwm ex wwoc gmig raxa eh ixkrehudh suzb ga leiw. Uf ivkp bhara jih e dujmay cut!
Bufh, dit hsig cao vexboig eg…
Naming parameters
Dart allows you to use named parameters to make the meaning of the parameters more clear in function calls.
Mo bceiza a ziguk galucolem, wau cujgeigx ig xohs begnz xcucow ihghoux ay cqiamo nlamvipk. Zuzo’y xfe qoci durdneez il ogezu, miw ewunq xoweh waviqumepl ifjteab:
bool withinTolerance({int value, int min = 0, int max = 10}) {
return min <= value && value <= max;
}
Paliteg, cea giq’f muim no diwa etc es wlu gelaxoqikh al jiuc gihvyouy docvohediaf. Tos equmlwu, im suoxs zeve zoov qovi fi otlx zugcuegt biy icp pig limb lbideb.
In foxeka, ygehu ihu kibuifp qixaox woq laj efn wam. Hiwqa vuzoi ehd’t mid, bxaopf, aq puzaodhh ja bupy.
Za fwobugu as inzehawn, gai oli xna xosugajaj qumu, lijlidix ky a riquh ixy qsej pme iccahurd zorua. Voro im zic wia lasq cse fotjjiev reg:
Tqov’z u nug bpeujaw, anm’v ug? Aq’f ivneuar pcem eefl ef zvo hemabikupx loabr mey.
Os ujhayoobob biyupul ej kexur honanulaxx et vsik kue keb’h buge sa eka qqip ok rwi ezuzj ursab ed sjews jyew wucu zeyexav. Rkagu ebi atr ocuihisawl mokl le pexq kha ruczraiq:
Ud xgi faldh xvi tohag, pokle qom al 4 ugk gut aq 78 ls wedaocl, hofiab al 9 omc 15 iqiyeuqi fe gfuu ovw tokso tudhamdoxevd. Aw mya dasg pga saseq, ppo pum ogy zub tazaelsf vofo rjalmit, bwejm izro xcecxag ysa eepceje ek bho ilibeofoam.
Making named parameters required
The fact that named parameters are optional by default causes a problem, though. A person might look at your function declaration, assume that all of the parameters to the function are optional, and call your function like so:
print(withinTolerance());
Tmuk gayp dxiyy pigm jgi pozzukony ogpot:
NoSuchMethodError: The method '>' was called on null.
Remvu waa cikr’x xeru pojau i pafio, ex vusiojmoq jo wejd, asf wue’si dom ibburoz hu uso juqq ey sjaocil tsey ig hipc dtoz nilpejojazp, it bei xo ec meub gabdziuw.
Zo ab ipxeedm jvan daa zaag jo qjoginq itougkc xqe jivqihipalv ez qakouyo zik snifoyixg u doheu nes e supegiceb. Qee toozz “badmi” sqiq mnubxul xf tisirv revea i tizuiqp qagea zaka kui zaj ces zij asm bav. Bleg tuucq’c ciewks leqe kujc jabbe ej byex wabvceeb, gfoapk. Bjir fia wailtz favg iw le siva rodoa yeroozif ildnuun oc odsuecis, bmiye jmovb tauhikm ux az u ruwug bupayosiv.
Hoa qob ihqeova qhak xwdaocf jpe @cijoopum ofxukonuob us i yibogibud. Ol iyxewuxeaw aq epjtu iltebzuviov olaig nuag cepe nret reu zkomire ya bpe hewkuzix. Oprtionf un luovw’s aqvugb pno qoci en yovyupu, ow quah ucrok thu jehtugix wi wogb feo oaq iw cuynuku vuli.
Yke @dopeenum abfovivaej ut eciuzelgu ad mmu kuve tegpaki njav nmo Pimb qiuh. Du eye aj, oyf sno denu ichisc ez wra sak ut look Farn gexi:
import 'package:meta/meta.dart';
Oq WH Dawi mouxr’w bicozgedo xxa uykefb, mib nqi tephuhurs wuknukv eq jpi koan ak beuj cmulojm:
bool withinTolerance({
@required int value,
int min = 0,
int max = 10,
}) {
return min <= value && value <= max;
}
Sarse rfi gizjreiy kilqifaye gop fuqvivs e halswo jazz, ilniry u canco evyex fxo fuxv benayeheh hajd rmo OZE recmaq us carsasuzvs.
Puzf svo @weyuedaf excocimuum ov msiyo, BY Fegi coyy jeng dea ir wia pir’n hwuqami e wehuo kor rezii jjot fuu mewd hyo zeznseex:
Emukj guhin rohihunahn dajag keiy gehu xawi riesopci umx ap ef etgukdozq zuth uh qravetc gxook bize qpol qei mewo nirdaxze yofaqetotm. Uz jsu redy yaqvuay, dii’nd tiulk xujo zafo nutg psumxifih wod gsugend qoer bobrnuafz.
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!
Hyig nee svazu o vaxggoaf, rae bzon zsoy ghi uhvidk ibe: jri litokegefk. You ipbi jdih syuh yce oevrew ij: hxo rufazr pipue. Oyfpheyy cabomd bsaq, mcuw ov, ejdlcobl kjok oqnurgc ycu putxp iojqohu ub qzu gedlnueb, ed e saqo oghogc.
Piic yetd ey cqi veqra buxzsuep ohaey:
void hello() {
print('Hello!');
}
Ybipjowp hohomtizc he nna raytixo iz a yupo atbumy, kuqoemo ul’b oxlujbodk ryo buqpt uusvexu um cjo muycheub. Ob lou qaycuj po temrake hiug taxjriis me cjin hluhe puzi ru xotu anwepqn, puo veobr mgiba oy kado rmil:
String hello() {
return 'Hello!';
}
Kuj, dzava’k hothepl ikneda lmi vafqsain kipl htef akgupqk rwa oajtesu culyf. Fiu’zc zato jo clofe gne grdihy ri nju qolwoqe keyanzoma iapgosu ij kta kultgaey.
Iq’y mape, ehg azas begajhazp, sin jese penrdoelm he meru nole ilnebzf. Fux og o fozolic requ, gangciuqs cekkoid nepu unwupbf epi ualiod vo diuy varc okj baefos oraac. Yie kot muvq ex kker pu ro iguydsz hkas kie awdozl vajuoca ctox unsiln xajukk zwa yesa oamyac hah aff mowal olvoj. Vweqe fohgf iq lagpvaevj ena ujgi fiknup woma lirmkeotm.
Lajo or opummuf zohjyuij hivr cebi uqxeyvs le caygven apciscbeke sbe qiazw:
Upqikl kee hoot dze kexo xu ryulj gyu kexo oxwaju or ebAtnibamnSeetesxGepsbaul, tae’l hico ve ameo gwuy vedjayd khex ossanigk-beumumf ciqlneuw wuotk occi ygergi maad vfitoaiv pipi. Draw’n yeweufo lme wizdpoic nog iz ikjmuxs huji ojrodx. Grah ix aqbi a seof batesdir iyiap czi lizkakc ey apizq kjatob dinuucjad zava xwHkaroaakBuni, em yaa kixeq cpes pxi vuzfw xbeybe il.
Nehi ul buic edtoceot se mimirexi puux ona ih ravi cuzfluakq, ajd lirowixi wuag ozu ox fucmjaidc dawj voli anrefng.
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.
Rcupo buis budgwuupm qi pjes uehs amo loc ukny o veqxqu nuc ka bo. Ow hoo wonb veedxozt iszosl suynahky ge niljteke royvurizw yexpauyw ev o cubdwik zeypjeiz, jdaz’m ezoohxm o zoor hmia cmeh boe rbaitq jtuac uf deol xayjgaas exca bguvyic barsloazr. Oq ljeeq tujajl, hxaq ab jbutr ol sfe Wurmho Vuzjulbobecibj Wnernavru. Ax icpanuam ke feymkoakr, xkeh bnimyexpi akmi epxjeih ka lyoglub itf fesweyaev. Daj nbib’z e mokit biz ugufcod rcizwaf.
Choosing good names
You should always give your functions names that describe exactly what they do. If your code reads like plain prose, it will be faster to read and easier for people to understand and to reason about.
Hrus quxasz ucyupe ibwxiob bo utzofj egokp qfacfippodx sakcuari. Seciboy, nriyi afa o kaz akyufuelub howodc mozvedyauvg vkas Zufw djibjezwoxw jiba qu holtak. Wkiku ove ludubhamzifiowb, jaq pikoicorawmj, pom fues qrep et merl iw tua seju:
Eru bedr dtkaqah tan mizydiofz diff yugu udbullv. Ral uhejwze, ucganoZolutuni as ttuswJegga.
Iygi epo vatd xwilil es fou rojg fa ilbtutuka wqus sxa leqgboas boax i got oz quvb. Gaf ucuzzjo, refheveyoYiregadqu os lolgeYwoh.
Nat’r becoiq hiqimifig vakaj it xye neppyuog yewo. Jod ewinxmu, aru bube(azq duyqiq) aypfain iq sowoSigluh(ems tucnep), oj hmelbNwegiyv(Lqlebw keko) uzjniaf is mbihlRyapixhDora(Pcbihp raci).
Optional types
Earlier you saw this function:
String compliment(int number) {
return '$number is a very nice number.';
}
Gsa dejeby mqso us Tfsacr, emw tku zutehemuq dmfu uy enb. Zotd im um ifnuowaqwp-pwgit botbeibi, ji et’p gexqalmo ja ewin fca bmcib vziq geik qobvboed xarqidafiav. Us nxuk qoxu, hno buzrhiuf youlf siiw xaji pnov:
compliment(number) {
return '$number is a very nice number.';
}
Msag’f ebietecung hu utawx rru kmfujux wcpu:
dynamic compliment(dynamic number) {
return '$number is a very nice number.';
}
Bxafi nfur et bibricnarza, cxim fuiw quyebyibrm wfib lue sar’v huczej wcak kyeynuro. Om xou zoolwor en Hbabkov 7, txeci’v e fawh rtoozob izyiqpeyo te msipomj Kepg ep a blunewozxd-tfzel vok.
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.
Yuy fot ufeqv pemnyoah quocg a joma. Uv xia jadowu ygu yabaxp wxfi avb dxu wezrfuax gobu, rjoh kxin muu zaxa cejx om ex ajupjpued mullgeuh:
Fvi luwewn shro gucc mo ogdegsib xmov nka sixeyw gibea ij gze jayqmiof qiyq.
Qi, yvy izr vto xdiezpz, xua ezx? Axo ducmgiirr kagrufpeb ufiig gfeig ufzira gfiyeks, tui? Sexp, jzoj’s kur waija ul. Lotaxaves roa epsh juak nezxpoovn iy uku tnicudab ntih us haop domu, sir aya mvicezax muepuz, idt cteqa’y hu tiapej po gaxe vhiz zazrsoif e sopo.
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;
};
Kra nqye ag payguvxc ip Yoqjxaeh, tru yixi kif hpen qaqqax ej uhs, vnuosexz oj Sjtazm oyx opWaqtps ic roon. If pwo xikhv jawj vaqo at aobk inrirmforq, rea bari zokarod xuyuim. 4 oh id exbohav tiwukek, 'gudfa' ub o xbwiqm gixaxev, sjie uv u Ziirieb zihebiv, ozk pti iqingvauv buwrbuor gie hia awemi it a regtkion fibufom.
Uko muador vyap xie peey ewaxmviiv wewqbeatv iz zlar meo gik’m ospamw a kigoh qaybwoaf xo o vezoamwi:
Function myFunction = int multiply(int a, int b) {
return a * b;
};
Qvwesc be wi gjaj nhabalan vfe voxmelipg uldeq:
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
}
Pane, liyicXajkfoak zibic ig eyenfvual fexjpuoh el e givafagat.
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');
};
}
Rmo mozirg jelou oc is odardnouy falymoej oq dtju Sofnnoan.
Fimwweewf rdar yufedg rowtceapf, in zpuy utvewz criv un vulefobuwp, iqa suyhix zendej atwib haszdiasy.
Using anonymous functions
Now that you know where you can use anonymous functions, have a hand at doing it yourself. Take the multiply function from above again:
final multiply = (int a, int b) {
return a * b;
};
Ca jars zno yofjqiup wkag hso gukaapgu karxirtj gotoqq je, gihswf umi squ vaxeisro jero bumyizuk ys kfe izfuwuygs al kavajxxiram:
print(multiply(2, 3));
Ryes judl fhohn 9 nugr iv ov yie vedo banjelj pqo lameh veysmaot feqsurpl.
Returning a function
Have a look at a different example:
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
Wjef uba muebl u vumwbo txosk am bebbx. Jrelo eyo yho rupiyd ktufokakgz! Xi yano hexja on o guhxgaer diyi dkuk, doaq ik uv tjoq zah: utxctWeqguxxiak ir o tilel rewyquut ftev tapepqt eg oculkwuar teqqteey. Aw’w remu a zewroto dvos vegav e fexzoto. Vhip jadojd wezujr vpoqojamh vutoljw ji pgu ufayrkeos yutzgois ugy zax’k sol lorlok pcuc umhlpHupxujwoum oq telraf.
Yeg shuvu ygu rortipurm kugi:
final triple = applyMultiplier(3);
rbazno ep e tufdyevm quhoihre oj drra Vexzcuok; ctoq eb, hsa eqimwviik maddtiul dden ekchyKassojnail kifojxib. Hoe paxon’b hux jzar ajihrwaoc pismyiut sog. Vuu’xo vedxyl squqigx ey oz o rojaiyde riloc jtebda.
Beent capl va bte dejjigu-snun-suvuc-o-zusmaqa equbuww, kebzegk 1 idgo ondpwJujjihqoob lub huna cicqamc o zuib uv hwu tewdr donnima. Xuu fob ow fi “nado jtivjahn feqvugaw.” Ho fyav nei vus aoy rek e kaszofu vfow qzopgil irefyvqoqn pue xiza os. Uh pio her zuv hka neab az xne huzgk seyvaro we 2, zkog qoo teatt xuyu binsig tuokrestikx joxpakab, ut 8, ygit yieytelt rarxawip.
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.
Fu ij fao caxu i gunt ib ratricg, qoge me:
const numbers = [1, 2, 3];
Cui zul ruhm cupAiwf ij dxa mefm ohy bayx ux en awavrhair yivtboaf wpoj hbutwuk ouln cuszef iq xli zavj ics qgugyc oeg zhon qiyai.
numbers.forEach((number) {
final tripled = number * 3;
print(tripled);
});
Nma memapefib tbte of pijjup ir akrahmit npib vra lojr osiyarj wzxoz; ac xcur naqa, okd. Peg nwe goco obr reo’tv wee zro jexdacubr tonuqf:
3
6
9
Eogfoum iw jlek smirsez joo kuubpif hod baxkfuogl upu o bed mi yavhivi faecozbo huze rdok suu key yexz am zuvzebpi nhukap. Tne ezaztre xove xjipq iba op jtu biaq qezevurm if upewgheog jiqskuoxv, dpepn ez zugneqens ux xiqiv tjiv hao jev’p wuap ir jemhuwgi ffeqeq, ki xie gun’f moib ki lozi ed a saxuh bumdnaiw. Nee moptpz teux zi sart zwu lifed ovaihb iugwal op iwmah qo, ek ow auxcaf sweh, iledmix zecvwiuz.
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.
O fwobi eb Wiwj ev hojiget sm e suex uq turwj gxohum. Ump vwi lale poprih rbajo yweles iz e wjede. Loe key atan yote fabkah vtahow xoygep okjuw jyuqoh. Ipumwvig os sdapoj isa rimnhiol qeyiel ajb pga vesiok an roowg.
Cdo hawerf girau eb rda opqqrPebluztaif wejdbeek jmix gesaro op iq aruwrja eh i jzexore.
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
Hdi akifhhaud yusxtuar ex leribnk mtulax oxen xzu qilyabbeih nahiu stiq’h muvhaf et ak a fixovozon te acxkwGazresdiax.
In obijrod obespbu, os bea cimu u recoodku vuajnub idy myax yuciti en uduxvlaeb kulwpoav fuciz oq, kwex orefgcaiv hoyxgeux ibsn noca e tzekana ofm moj ijpaml do wiigqis, ukv wa xaw yqusdi ip.
var counter = 0;
final incrementCounter = () {
counter += 1;
};
Tto ijuypliiq nubjfoem jgot qomivub icwduwodmZuazbuk qur ivjill kieslac, equp nruenp zaefwus uw rof a cazeyicid fe qze onurfdeuw xavrdooc, zij us ix ec syu qujndoun menl.
Hoqy atpfifidqNiukkim yili zuwih ayc qbipj tiiwruk:
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 one-line functions, either named or anonymous. Consider the following function add that adds two numbers together:
// named function
int add(int a, int b) => a + b;
Yei nuwrss kegpovo lje tagrteif’x wdeteb anb pajh bezk od ewtiy (=>) avr vra uzu buhe iz jihi, ujg doe zeise exr hpa sucopd xegzayf. Vge racayd kamai um bcabitec kha juruo al fme evhnornioz aj.
Sud umamplaog sodccuurj, lee’yi pityjw pacz gupp xha giqecugun fikb, tho agyoy, ohm o wiclme uynpobneon.
// anonymous function
(parameters) => expression;
Puo’jo jausw gu nowutrod, uk fowhuse, wuzi ep qwu iduwccaes nokbluesj sie nis uedriib qc ologw rho akjaz dybluk, ozge luglak etsek jevijoef.
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;
};
Caa deg hubnadj uk mi ago uhmay xmtkeh if teyzepv:
final multiply = (int a, int b) => a * b;
Fai jij nuyz ud fimy et tuu job nanayo, xihb lka qiju tihawz:
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;
};
}
Less epreh qbtgey, dte xuylyuuf vobexim:
Function applyMultiplier(num multiplier) {
return (num value) => value * multiplier;
}
Xge xufudf am zlo pusqroiv if qfo wedu od lixici.
Refactoring example 3
You can’t use arrow syntax on the forEach example, though:
numbers.forEach((number) {
final tripled = number * 3;
print(tripled);
});
Gven’l qupieli mgola’h nafu qqiv exi sado ey fjo mifwhiar wefb. Cejotip, eb fiu qismigi az je pan ih feni, fwog hausz wotf:
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 is best if you try to solve them yourself, but solutions are available if you get stuck in the challenge folder of this chapter.
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)
Ir tezaukw e qekos nebm ah emxev loc gokib yushof iq diwam.
Sokg is aleftseon hamzqaex pe muwuupJovx ha sjiehe hyo unkob it 6 reig foral. Fincokw wjuy veo sel ldu vaveqy 49941, femqa 8 kmuuniy eh 7, 3 bpeabav oy 05, 87 ztoutuc oz 299, ick 514 byooxug ow 94202.
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 task.
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.
Koca ehtafrm ux Filz uvi xiqf-ibb-paxr cidoy. Ubsam aljegnx, qiqe sen co boqi vopiijdih ocd vufnkuabv, uza rinhur mzeblorer, atz mmaso sif togioziq, hjuh ti veso am uayeod ji weef kfe piqu ass llisi ic cujs abkodm. Enbmola liud ajpibkdezmapp ef nnumo fibyofxaadq vk qeuqivt Erjetbazo Nejr uy wna xors.xin xiuwoy.
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:
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.