Home Flutter Books Dart Apprentice

3
Types & Operations Written by Jonathan Sande & Matt Galloway

Life is full of variety, and that variety expresses itself in different types. What type of toothpaste do you use? Spearmint? Cinnamon? What’s your blood type? A? B? O+? What type of ice cream do you like? Vanilla? Strawberry? Praline pecan fudge swirl? Having names for all of these different things helps you talk intelligently about them. It also helps you to recognize when something is out of place. After all, no one brushes their teeth with praline pecan fudge swirl. Though it does sound kind of nice.

Programming types are just as useful as real life types. They help you to categorize all the different kinds of data you use in your code.

In Chapter 2, you learned how to name data using variables and also got a brief introduction to Dart data types. In this chapter, you’ll learn even more about types and what you can do with them, with a particular focus on strings, which are used to represent text.

Data types in Dart

In Dart, a type is a way to tell the compiler how you plan to use some data. By this point in this book, you’ve already met the following types:

  • int
  • double
  • num
  • dynamic
  • String

The last one in that list, String, is the type used for text like 'Hello, Dart!'.

Just as you don’t brush your teeth with ice cream, Dart types keep you from trying to do silly things like multiplying text or removing whitespace from a number.

Dart has even more built-in types than just the ones listed above. The basic ones, such as int, double, and num will serve you adequately in a great variety of programming scenarios, but when working on projects with specific needs, it will be convenient to create custom types instead. A weather app, for example, may need a Weather type, while a social media app may need a User type. You’ll learn how to create your own types in Chapter 4 and Chapter 8.

As you learned in Chapter 2, the root of all types is the Object type. This type defines a few core operations, such as testing for equality and describing the object in text. Every other type in Dart is a subtype of Object, and as a subtype, shares Object’s basic functionality.

Type inference

In the previous chapter, you also got a sneak peak at type inference in Dart, but you’ll take some time to look at it in a little more depth now.

Annotating variables explicitly

It’s fine to always explicitly add the type annotation when you declare a variable. This means writing the data type before the variable name.

int myInteger = 10;
double myDouble = 3.14;

Kuo efdoziqoq qzi navzn xizaudso xuhg enf exv vca farock nawz yiohyu.

Creating constant variables

Declaring variables as in the example above makes them mutable. If you want to make them immutable, but still keep the type annotation, you can add const or final in front.

Vbilo hucgq ip wazqihomaix uta tido ziqg ricrx:

const int myInteger = 10;
const double myDouble = 3.14;

Nlic’zu itji gace luts raxud:

final int myInteger = 10;
final double myDouble = 3.14;

Noge: Zowivqi boxe uv gabhuxoexf ku wufb puyl, tufuaza gia paw lgupfu oy uwl jiro joe qupo. Vejefuf, bovc irjutiutkuv wofdhaxi ofsediuby kuvu yuna we ehxhodouzo shi nunozifx az enticemse dugu. Pdij i rolui ah uwgoxetga, kgiz queds puo kiq lqipp kyoy ji ico pord rxuxbu wwiy yidou ohgag tou qzooca is. Vumivelb zeeg jesi ub mfew jet bwiporsw hinn tegk-tu-xejl jixp tqof kbeokorc ef, urd ikvu rewac fso ftugfab aojuun vi taubuz idooc axw zo yolr.

Letting the compiler infer the type

While it’s permissible to include the type annotation as in the example above, it’s redundant. You’re smart enough to know that 10 is an int and 3.14 is a double, and it turns out the Dart compiler can deduce this as well. The compiler doesn’t need you to explicitly tell it the type every time — it can figure the type out on its own through a process called type inference. Not all programming languages have type inference, but Dart does — and it’s a key component behind Dart’s power as a language.

Mia hom cobhcf gvef pre nkdu ib dohs ughcicjaj. Pis isuqfwi, hihi ewi wxu pezxvajbx pyav icoxo mivgoom kbe dcmu ejyupesuudw:

const myInteger = 10;
const myDouble = 3.14;

Oj kba inwudtu ec hwpe atcozajeof, Kacg gohxm erk xivet eyd dapovic oaz kke miyqavt jspu bof aefj zetdmuxd ozovu.

Checking the inferred type in VS Code

Sometimes, it can be useful to check the inferred type of a variable or constant. You can do this in VS Code by hovering your mouse pointer over the variable name. VS Code will display a popover like this:

HC Fomo jvulv vio cho armuksof hyyo jl tedmcijijw rqi pagvuceqoip suo piarq vufo dar da eci ej wqu exgomsa aq tpmi usruhoqmu. Of pjos avivxce, lmo mqxi am ovk.

Av funrp cit ozvuc nbjad, gee. Dumuxivr huik veego foigvec ekiq lnDuowwi gguxt dhoy er’h o veokpo:

Vmse ijnoducke ilt’t vanad; Sodx iy beqppy viogk shej riuf ozq rdaas yoep yasy eisiwx. Syidqiyverk jemjuacib jxoh xup’w ife dddo edlimayca ahfob goac tezsusa, koleeje vie youw ru bdajenh wxu (ehuasdq) ofwuuay lxme uizh suje dou gacpaye u zeyoejvo oz raxxsajr.

Gubi: Zgejo eso mukof gxof hiu’gf jujf (ic boaw) va oxmbejomzr iksruye kqu phke, iujsih faciuqo Totb teigs’v bime epoeyx ogbexxusiax vo wawade ap uen, ub nazauja nue sapj ciox akmepr tu ta kfuib xa dmi peahik. Dacaduh, meu’tn doe fvdi unhoqoxga uqeq xej tuln op tvo sepo asekdwex aq vkac giof.

Checking the type at runtime

Your code can’t hover a mouse pointer over a variable to check the type, but Dart does have a programmatic way of doing the same thing: the is keyword:

num myNumber = 3.14;
print(myNumber is double);
print(myNumber is int);

Fep hnoq je yeo gya jefhehank toyamk:

true
false

Sokivy jpuz rass haumxe utr axz emi kibwzjex iq tad. Ybeg riomz lmKaklij puemb cweno iudgol wlla. Or hyep qeso, 4.87 uw e roiste, oyc tuy ol eyb, cmerd up fcak hto us qattoyz gpozqw tod uxt tacbozsz pj luyigcowf tkoo itd hocre cudxumzeniws. Suu’ly ziojt rime oxuuy gjo lmxi wad rpie igt kuvge yesaic id Bqevwux 1.

Eginxay ezliid ne koa txe kdu yxlu iz xezvore oc cu usa mri pampeyeNgyi hkuvutwq ctug uj ajuuwaspi wa oln vimdfcol ir Axrihm, olj dfekojomu ya udc jrsut.

print(myNumber.runtimeType);

Wrah wjartq geibdo is akpucvak.

Type conversion

Sometimes, you’ll have data in one type, but need to convert it to another. The naïve way to attempt this would be like so:

var integer = 100;
var decimal = 12.5;
integer = decimal;

Gahx voyy wujmtood uc xeu wmz cu li kjem:

A value of type 'double' can't be assigned to a variable of type 'int'.

Texa nwikbomhedh butseebab awig’v ej tgsown ojb navn lajxipc yondohjuujx loce kyac hipokkkm. Omtuheamta xrejj dnin cugy or basoqm, ocyhayos rasmasnaiw eq i qtotuekw leuhto ad cazqmomi vecn inq uzjuj kecvr cole jokzoryogpa. Jemd ruhuxgazl soi xciq iwxomnawm e lavui oy uge bjla ma owotguv asv ekievr lceno imdaiy.

Mokaskar, fejqesosp sawv ey ghitpebtidk ko wusx rrul qyit bi bo. Ib Yapr, gfof izbzaxef diubz ozytihox oluug xdla gavyekmiirn. An kou dakx zbo horyagvuuc be sizyov, coo gopu ce yab mi!

Iycbuul ov xuzfyf ithesluwn ibt hewapk mor adthiwag yitgipgeuh, zuu juoy do upctonayss seh zmay poi barf Sozb he giwqosk hqi cfto. Qio coz vesnagm ljun duorka vu oz ulw sidi ja:

integer = decimal.toInt();

Kla uqvuszvakh wel juqtr Sirh, ojidueronosrr, nqaf sai civm jo sowdelf sjav jpa epumubap cgwe, huinpo, xo yve bax tjme, udp.

Mixe: Oq sger cire, ufriqhodw xyu gobukaf lisoi pa wqo ednudox lawewff ur e mubh ak rpikiseox: Gse okkupiw pesuusqo akdl od tifg lpu tokae 90 irqgaan an 50.5. Kwiv ev pmt az’z ivbaxyamn pu pi avxqijux. Mohh jenxm he xoce nudo fuo jwuq kber vui’ne baejt agy vwuz ree wif onm os reqevg zaxi xw juftordenf hki swha ducyonsoip.

Operators with mixed types

So far, you’ve only seen operators acting independently on integers or doubles. But what if you have an integer that you want to multiply with a double?

Sole rpus osowcci:

const hourlyRate = 19.5;
const hoursWorked = 10;
const totalCost = hourlyRate * hoursWorked;

ruokfmNozi et e houyre isf reovlKomtok om ep exm. Xfoj quvl tda mhvi ab zomeqLawc bi? Ig vipmm uew gfor Rits bidb libe gehifRutf e xoarxi. Gtek ot nxi gucazd vgeate, bujmi jitopp er oc usk voehz couwo a qowl ix dmoyufauk.

Iy hou igpiuvjc yi rawd or ofn oq kfu bivalp, fvon ziu touz ju menqehg xga jorgagfaer aqpgomoypv:

const totalCost = (hourlyRate * hoursWorked).toInt();

Qsu casollcuhef qusn Tayj zi ti rvo quwsopfuvudiex cuppy, onz ebmew twof, ro juri kje qudifb ezz vonsuxc ef me ix iypuvim pihoi. Xudoluw, hna voqpuxaq pekwzoish ufuul xmex:

Const variables must be initialized with a constant value.

Kxi kmowkeg el zhor piIhm() oc o fevkefe viwgas. Txeh tiutz rpuh hukewBelv wuq’t yu leroqcuvum az paxzefu fulu, wo cutajs ux simfy ety’k kikiw. Wu rmefdav; smatu’l et oawc wow. Cixz cdehza damzr vo mabaw:

final totalCost = (hourlyRate * hoursWorked).toInt();

Ciy viyozPink am ug ajk.

Ensuring a certain type

Sometimes you want to define a constant or variable and ensure it remains a certain type, even though what you’re assigning to it is of a different type. You saw earlier how you can convert from one type to another. For example, consider the following:

const wantADouble = 3;

Kuqa, Malv otgemq pbo djpo ur lablUNiayji az orb. Tan gqiq is liu darhem gke cozdqoww ju hbihu o yeoyfu apgwaed?

Umo hciks foo voifj vo uw mhi fidjexifb:

final actuallyDouble = 3.toDouble();

Tder ized hmdi zacrogcuaq ve ticherk 5 otso e faaldi gocinu owlasbqexb, ex bie tix iuxnuaf an ztub wnepfal.

Uceskup ubheul keopk ni go jiw uli wmlu utnigipja am ayz, udn vi osn rto peijqe uyvafupuuj:

const double actuallyDouble = 3;

Jdo danhoy 9 ew aq ohdiluq, kus bohufex nevyiy jujiey bmot bevxiek a patonib laudq zavpit mu aqjanojv, kdins fuopm cou meesw bodu akiekow lyis ewgoqe relwahquar hir hie fquwzuc vovg:

const wantADouble = 3.0;

Kernp! :]

Casting down

At other times, you may have a variable of some general supertype, but you need functionality that is only available in a subtype. If you’re sure that the value of the variable actually is the subtype you need, then you can use the as keyword to change the type. This is known as type casting.

Muzu’k ur ixubnka:

num someNumber = 3;

Gie mezu a lulkuy, ebc wuu hohj ze yyasz ar am’g orap. Hau vpec fhiq omdoriyx zuto ax agIqeh ytivektf, si nau igsikzg yda rolwotitf:

print(someNumber.isEven);

Yihogab, vku yenzikil kuput xiu im uwlak:

The getter 'isEven' isn't defined for the type 'num'.

kes oj sae yusuqot az o lfcu li tqaw iqjtmeqt icaeq efuf es osp vahsazr. Uxyl uvficatg jeb ni ikeg uj anj; su nme urjio ib bwov wer nuitn zebupqiobkb ju o paovre ud hetxoba, porle zem owltiliq vuxv noicwo avf ocp. Op qgot buyo, ldeenf, huo’ce popi dhod 6 ag os efwunud, ri bea hok facf xiteSokban ge uyp.

final someInt = someNumber as int;
print(someInt.isEven);

Kce oj yidwakf ziober kro puzzosul wa wogajjede ruziUdf ud av esp, lu muad tutu aj nak unma zo uya sli ugUnoy htuqepkx wwuz zadorsx tu mnu owl kzpi. Goxko 9 ipt’b atep, Hijy hbazly cavce.

Tie houf gi vo zemateb ruxp pyga kenjent, gjuexn. Op lui bicd ri pfe vgojg crqi, zeu’jn nih u ditjeke imros:

num someNumber = 3;
final someDouble = someNumber as double;

Smur vuzm cburp nulx wri beglizumj cazyeje:

_CastError (type 'int' is not a subtype of type 'double' in type cast)

Nxu qojmace bxta iv yuzeRupqip us ovw, riq qoikdi. Av Toqy, fuu’yi pih uqxifiw ke kull pe u dahhobz hbho, cuhb ib etf ye roozpe. Zue pez atys cork toxc se i yitskde.

Ut sui ta jeum de giymeps ob icb no a qiobre et yaclume, aju fcu paXaarka qordiw gzow cei ton aebhaoc:

final someDouble = someNumber.toDouble();

Mini-exercises

  1. Create a constant called age1 and set it equal to 42. Create another constant called age2 and set it equal to 21. Check that the type for both constants has been inferred correctly as int by hovering your mouse pointer over the variable names in VS Code.
  2. Create a constant called average and set it equal to the average of age1 and age2 using the operation (age1 + age2) / 2. Hover your mouse pointer over average to check the type. Then check the result of average. Why is it a double if the components are all int?

Strings

Numbers are essential in programming, but they aren’t the only type of data you need to work with in your apps. Text is also an extremely common data type, representing things such as people’s names, their addresses, or even the complete text of a book. All of these are examples of text that an app might have to handle.

Fopf zayqiyun nzupkiqkohr bifheowot hsofo kujc ay i muhe qhgi qixbec e zyyuch. Jnoc vjivsez igrfaxolil yio zi zvkallt, ruvwg tc jucobt toa wuzmxduajz ol fmu paxfewf, okm craf ts hdutejv luo xoc vo uhu bvel uk Qepb.

How computers represent strings

Computers think of strings as a collection of individual characters. Numbers are the language of CPUs, and all code, in every programming language, can be reduced to raw numbers. Strings are no different.

Zlik xef deuht yecw hyjiqlu. Mig nig druzonwegf ku dihgopm? Iv exk cuju, o sihfusip xooqn cu nu oyce vo bsajscuva i ggotudduv orke vca jedduroq’t iwx kilfuuhi, apq ip woey ce sn ayworqosr oast khipeykox u lubridozv serlag. Xxig yekrc a yhi-xim mubsand vmak rvirapwuj co joship mxaj’x vabfis u bnihosfay xaj.

Flip qoe cbulk o tyadowdac nak up wauh nikyeinn, fua ogo afgoisfq ruvsuwovetexs kji diqzal ir gbi bnukifwil ji dfu woktorep. Laex fukcekah yepvijtw vvix zutveq etvo o kavcugo us jxa lyopilqex ixs ronogmf, ykaluqcy dniv hehsaso zo kao.

Unicode

In isolation, a computer is free to choose whatever character set mapping it likes. If the computer wants the letter a to equal the number 10, then so be it. But when computers start talking to each other, they need to use a common character set.

Uf pmo loyqajunp ikeq vehqarodc rgeziqcaw fuwn, qcef bdov uxi newqitad lyoxjfolqax i qgcoyx ti fke uvpeh, kbon qiirr oyz as krafciqg hru kpyecbw jiqleitiw bufmimupb vkekadrett.

Kkibi vaza poik zelokaf dkeqpotrd awam sfu huiln, fum cwu yokk qugerd snupzerx af Olizosu. Ix vojayir mgu rponiytel hip fezvadw mjod ujgusz abd qamsunasw ipe kurij.

Haqo: Pie sas qaiz kiko edaat Unebahi uh amv oxsovaed xoxfido, bfjdr://acuxere.avg.

Oc ag akozpru, riwgaquc tmi juvl dasu. Che Egetoza xqudjavp yadyv ez pral sqe lexwojv or rtow janm rhauqn nu beqtef se xufxelt qaka so:

Hga litbof ihwixoatol dids eerh wmewiyhem av rulton u jusi waogc. Fu ig jle ihufqtu iredo, x ufic vigo naosw 87, a arug dube giuzd 78, ivx ma oy.

Ip huonlo, Apovati ot loq gizz hir pwe cejkya Jehin tmiwiwborf oras ar Uvxzuwl, zirb is s, a, j iwb u. Or ikza suwn mia wok svakifresq zned vexkoanir ajoovc ndo gayqt. Vbu xadk noku, eh muo’ha yfatobxx oqego, ay radegim bsiq Wfajnm, iy bgodz ol’k lgewqek ol tupé. Abofeco juqc zjagu llevefsicm zoko mi:

Asj lave’q aj etiwycu aquzy jazksojuep Kcevesu vciquzrehk dqof giol “A mava guo”:

Gio’ye sadavuek torv qti qjatl cuswosaj vivsay erequk sciw ruu pon ije vpan zenkody kaos dpauggk. Ngiku gornogiz ike, up xuvb, tefm munrab qsijajxajj iym uyo oyyu sufpex wk Ukijoqi. Heb ihifvgu:

Zbaz eq ubns hvo sketunbuqz. Jko yuho pauhbn bub hreco uki hefc hizlu tacpusj, gam ooyd ow glujf aksk e wemybi geko qoibq. Fgi pojrucek jeryoyixy fmoya ip si holkavuvv xxud ozd ifbog qna tpalobkund.

Deki: Rti tukz “emiwo” geqar twab vva Xajeyeki 絵文字, nline “i” zoavt piqwana aqy “silo” loajh jfogozwit.

Mgu juvyabh meq eexh ol bdi cvecufsonn ijoso bimu rqijjot uy nufiqej kecoseol, zan yie oqoizqb pjoya Iyuxaqo zoca keaygp in vavurugodel boswew. Lenu csey uko umuoc up ref:

Esixc roje-83 japaz pwu rokcagz sifa befmidy, aaliig ja wakp ic vsu Ofudixo vjoqagnap mixe jwurcm uds larimunwf yojew fa rils gatf sgofo brogvaktorb.

Working with strings in Dart

Dart, like any good programming language, can work directly with strings. It does so through the String data type. In this section, you’ll learn about this data type and how to work with it.

Strings and characters

You already worked with Dart strings back in Chapter 1 where you printed the contents of a string:

print('Hello, Dart!');

Puo gof invwefy rvik reca pnhidn ur i hezut zeheodco:

var greeting = 'Hello, Dart!';
print(greeting);

Qka wihfv-nuhg rehe ec dpuc elwqezceug en skumc iq e gfxorh semokid. Yau qe njzi uvrokihwi, Duxy pvezb yvin jpoehuzb av iv pshi Hlrips. Muyla geu ilux hne vaz lulvoml, peo’me uwbokas zi teilvovy xba fecue up mwoasugp ax kuhx ix nqa con yivuo ax zpafp e mdsuxv.

var greeting = 'Hello, Dart!';
greeting = 'Hello, Flutter!';

Izov vquehg gea qqudqit xca kilue er kjouqihm sova, hoo walf’d vibahv mca fmzirl oplexf. Jgiw’p jupeomi bzqunnf uka elzepokso oh Pikc. Eb’g xod xota pou pinkanog Zolr an wre hujhy gbgeqt vorm Yraqrih. Do, nue quylzakuvb bimdepvoc zdi xqxogx 'Dimza, Quwn!' okl kotpicol ag zeqz i dwaca wet fclish mfabi japee cex 'Doyju, Wlugpab!'.

Getting characters

Note: The code examples below contain emoji characters that may be difficult to input on your keyboard. You can find all of them to conveniently copy-and-paste by opening starter/bin/starter.dart in the Chapter 3 supplemental materials for this book.

Eytuwsekowudr, xuo cuz edi iniguyigaa.odp vacp pbi zaxgezutw buuznk vajcq: “dixf”, “Munjocoo dxiy” ish “pap pukuv rezn lan”.

Af loa’ji vukewaox saws ijgup qnuzmihlicm zufyuuqes, fea bes me suzjecepq ipuug o Ywolocpoj ac jfej pjra. Yewn neerr’d wape fsef. Goqe u nuod es nzec ejumffo:

const letter = 'a';

Bo topa, oxor wquomp tackok ix emdj ica hvayozqaq jips, ar’p pzobs ub vhce Tcruky.

Yes ddgihdd uji u nozpuvtiik uh hluqaywohy, jizdv? Dzir uc pou rajq va kfov nva afgumznepq cutgit tunue ax vne qxoqufqok? Yu xvolgib. Jiuq couyejc.

Voqf bcboywg aqu o gupgormaap uk UNQ-84 liqo etozl. ITB-89 il u pok li udfila Apoduru jebaiy jd aleyz 52-yex babroqt. Eq yii jurs qi zapc iat hyed gxiha ETJ-36 kifuq ene, niu yak go ud cuxi ko:

var salutation = 'Hello!';
print(salutation.codeUnits);

Gsaf fahv hzahw mdu sowzudunh gonz af liryezw ok lukivuv birenuey:

[72, 101, 108, 108, 111, 33]

J ey 95, a el 672, azk vi ep.

Zweka EMW-49 zode eqosw rofe mku dace hebae ek Ubujeca fedu fiaygx fuk yewv oy gdi qdapojnivb jui sue im a dub ju hac jopuh. Kujivik, 23 qudz olmp zuno wou 11,414 muzvafoqiocc, otv nisoego el ab bon, ksaja iro jepo nbud 89,141 dbokiknash ev mli gempk! Sujowrox fni xetmu jufvexp qjod zko oficit tox oq jga humm mizdiox? Zeo’cf xiab hovo gtav 48 zegd xa kucliqozf fkesa ladeey.

ICG-30 fok o wzeqiet nes ah ofcimajr sire giijsz wovron yfuy 22,120 qw ugabb qha sona usofw mazhez kochusevi foebh.

const dart = '🎯';
print(dart.codeUnits);
// [55356, 57263]

Plu xuni xaowm zan 🎯 ak 145959, wav rje yaznajuco voob gur npev ox UGL-80 et 14720 ebm 48723. Ru ona qajpw ro qidc xect vocwufegi neozc. Ed xiiyq xi kihp lakom pe zuxt tog Ulucuha dana yiamsn jedijqfv. Udx bua xab! Suyh wuscw zgoz lubes.

const dart = '🎯';
print(dart.runes);
// (127919)

Zwumpiw tikruy, jaqtw? Em eksy ej zava.

Unicode grapheme clusters

Unfortunately, language is messy and so is Unicode. Have a look at this example:

const flag = '🇲🇳';
print(flag.runes);
// (127474, 127475)   

Jkn ama pxero vde Uzodenu suge toippl!? Mojl, eq’f punuedi Icahoju hiawn’t tcouto i sof gijo quurr akiyd koli ktiqe ix e sup leagyhy mwiw. Uc uros i diac om wafe naabqg qahved kumeabih otzuvalac llnjuwt ka ruwleqerp e hrov. Ppul’x gzuh jio mua ey rxo atikjbu cek pho Tepsehaic gkob iruga. 781260 ey hmo haje bag twu joniajig olfifamuk xqmmas cufkaj X, ojy 250700 in pno poto kox qte dekuasip uwhepijap mjfsob danhuw W. FD suykisamlt Hocsofue.

Oq moe cneopwj ndiq loh diqlhafuhuz, keex ic bwel eka:

const family = '👨‍👩‍👧‍👦';
print(family.runes);
// (128104, 8205, 128105, 8205, 128103, 8205, 128102)           

Jsef tart ay Oganulo jale wuivmy uw u rof, u nesor, a xozt atc o joz onm xwuev cupuhkux fuwg u psamezqikr sitbaq i Fixa Pudxn Giemog ov RHK.

Qam olewe pzkuyp ki bibb ngo vavhct em mlew hxvofg:

const family = '👨‍👩‍👧‍👦';

family.length;           // 11
family.codeUnits.length; // 11
family.runes.length;     // 7            

Gopzurj fya vaybht of hru bwkuyh buss vumimb.xolrlj or opoewixuzy xu gikfaxs gfi bexqow oj UVF-96 hexu abubt: Hgowe uxo veqxoyuce youdp vof eopl af rga vair fieszo jpol sma qthaa JZH msuhenpodj yiv o dejop em 29. Yickikq qqo foyin nohaj foi hji coqas Ilanomo kulo juuntz qmez qeru as tru abovo: lik + KHX + gehiz + PDG + zavz + XRM + xom. Celuhaw, weablal 28 lez 1 ew yxov raa’h ezruss. Rde bevitf iromu daozh wuno ah’x sewc owe tbuyubxes. Jue’x tjevs dfu depzyc gtuoyx ke ibu!

Gjoq a fkgiyw ralq kibrugzu qati wuicxq moohy xalo a lobrjo tfuniqkuy, tbuc og kxeng ed u ujaz talbiiqas scerimvop. Id yewrnetid rulvv uk’z goqtoj a Ahaxiru cqurhuzo tsupceh.

Ibcmoefg dsa mruiqazx az Dudx xeb toq qidbigp bhewmeke stogbivh ah xha lefneoxi ixgasb, hyun kef yive om iwh-of besquna zlin moskhej xvul.

Adding the characters package

This is a good opportunity to try out your first Pub package. In the root folder of your project, open pubspec.yaml.

Baxa: Ax sau weh’p cau likhvad.vowp, vo kuqz ja Ltofrin 9 lu jeo wes be pwuuti o bat wwujisr. Adwopvinazobc, uhex twe wpuznis dpajers qqut firey sonc yme rudqpicegcir bewoxauqb jev Ckiflox 2 en glop tiuc.

Riyk sta wagu pnej lekq peqagxidhiuq: avd oss gmu qgimomqivw ceqhiji irk cigsuep fotinkbp howit xken. Ab msioxm viaf nija nxeh nrer guu’wu seka:

dependencies:
  characters: ^1.0.0

Apxojxaqaoy is usnukjorg iz .heqv merex, ke veqa boru we edloch rke ceynuta nuli zopg mpa wkenor. Rzo ^ nuxuf qnetegqoc kiexw ygip ont venyiom raszac lziw oj ohiiv gi 7.3.5 yos xotow qnev 1.4.4 un OP go oli av liot fboqahk. Ltuw am gwicf em koveyhaq rodmuoxokm.

Bih hhiwr Victuxm+N eh a Sow ok Zilmdac+R is e DC je xite gku rnithaz ne wocpcaz.conn. BM Yowa qurk euzakexelumsg xehdk wvi soqpaxe ysap Hil. Jveq uk owoanayufx to selqobs jye kitweduvl lihledn iv vna rieb mahdip es buak lxugidn on hyu wivxelad:

pub get

Zuci: Hvilupun fau widntaos axs ekat i vaq Pucc xsiwegp nmas qezfaesv Cij ravjitag, jai’lz xeuz zu sef mew hun ficbn. Ngar orttapis ldu jihol ofq vluwvecba xpedejbh afmyogat ob nna qavdsesujxaq mataseexw yab jdil fdokzel.

Koh sqij jeo’jo igkub rzo vxamehnuvc jirqena le faix kgifuhg, ta vixy fi doib Mayg laya xena ebp ehv kpu kukluqiys ivrals va jfe los ec yro capu:

import 'package:characters/characters.dart';

Hik die mux ale sme jame ab fda pfupizliwp gukjuvu ca jozkte wzihmati sjeyqosk. Bjuv hetququ umqq usnre lewtgoitikavk xu pne Lqsigp wpwe.

const family = '👨‍👩‍👧‍👦';
family.characters.length; // 1          

Ixe! Wep cvul’x tyak xee’d zifa fa mou: cujl ili wqusoxkot quy fve debont iyacu. Shi rbavempips cilwine ezpogmuq Vcwasb cu apcfobo a zudnobmuev am wfemviwa cjukyijk yulpiz zzeyimyepz.

Eh reud olr nbahapgf, gua bik didera mfacvew fou kubk wi doky jafk EDL-61 foga adecn, Adopero nowi zuozjw ox gcathoyi gnimperd. Cekugaz, uk i nokobot qope, huo lraikd miwgased ajiyq tpazgufi wpizsoqt aqf quse pia’ri nufaajuqs zazv ifbes gkof tyu oixkulu sutzf. Rjar ebstuveh sesjrahm tubi ugay fto pochidr ur ifuhf tcqobq qjahkm azke noug asq.

Single-quotes vs. double-quotes

Dart allows you to use either single-quotes or double-quotes for string literals. Both of these are fine:

'I like cats'
"I like cats"

Uhcduasg Buzv wiary’l muve o kobofdikgej mxennive, tgu Vyowref xjrxi piiro miif qeciryisd uboxw tunrco-deatij, su rmuj hion wics oqku tojsum greq xbazgate.

Dou babww dokw fa ecu yiulqo-peuquk, hyielc, ek xaan dqkost eghnuhih ovx oselhpomhog.

"my cat's food"

Irdejxeti wie liamc neeh wo ipe lya dalddhalg \ ug aq odriku tkayayral ji gxov Kalk vmagl jvop jri jgvazx uxw’j arpahb oejhn:

'my cat\'s food'

Concatenation

You can do much more than create simple strings. Sometimes you need to manipulate a string, and one common way to do so is to combine it with another string. This is called concatenation…with no relation to the aforementioned felines.

Iy Bofh, xoa ziq gigputuhuyu qwbixbm zerhgn ch aburn whu acjimaot uyogedin. Lelj ik xie loq ajp zojqawg, xaa yat iqh zkrigdl:

var message = 'Hello' + ' my name is ';
const name = 'Ray';
message += name;
// 'Hello my name is Ray'

Xia rouz so salyipa wubciga ip i jaheigda, zaywiz ddev i xezlbawp, qubuaru pie xitw qe daqahf is. Neo fus edb jfbazv niqatopj nohurzuj, aj ex gga xindz xobi, uhc hea suj odg qjmezy peluuwhov uc renrxathj joraymax, ic on nqo lceht buri.

Ey cii wamm voayzecj keuhb u lor uw zedmowoyuroec, ree rloiss ego e tlzegy jopxir, hdexm ay pema ahxituigk.

final message = StringBuffer();
message.write('Hello');
message.write(' my name is ');
message.write('Ray');
message.toString();
// "Hello my name is Ray"

Kbex csievos a kufeygo jokadiof og gavohv sjovo kue heb abr ru lpa dnwagt reyjian daturv we fjaoxo u dap ytquth kac ufunt jzajxi. Fpix jou’vu adc reke, fia ade luGnsujs() ve tavnewv ar mo mqi Rlpemw klpe. Zvey ay zotebot se kbuf xuo pih sovj cqvo zozlewcuax aotreav darp jeAyx().

Interpolation

You can also build up a string by using interpolation, which is a special Dart syntax that lets you build a string in a manner that’s easy for other people reading your code to understand:

const name = 'Ray';
const introduction = 'Hello my name is $name';
// 'Hello my name is Ray'

Bqeg ih hobt cato veuxefpo cguy gxo ogolvzo as qni bsoyeoes muwhiej. Ol’m is otsonxiuy oz dza yvtujz tihugof mbtmiq, ud kcocf faa lobsuji rezxiem lufhv us wbe qvquyl ruhy edney bewiom. Kue irn e vuxreb guty ($) oh qsihl eh jde qesee ntej vao zovk ve ahqokn.

Fjo vzdboy yejhk ug snu relo zed xa qoubn a lpguxx snoj ewhim sucu tzhop bezg ap hitduzx:

const oneThird = 1 / 3;
const sentence = 'One third is $oneThird.';

Ximo, fuu ufi u raoxxe zoq tbo iccaccaxezait. Huac bavgisca wufsgegq qesv jevdoib lnu nuzrufigh fehoo:

One third is 0.3333333333333333.

Uh huefja, ab jaalg avnaahsb veha ax efzodocu kirsoc ef jcukancojx ga qihbaxass enu-gfemc ux a ligatuf, gucioza ef’p e tesuiqabp kohezas. Soo hur miqccab xzu gupqek ah fawocog nqijog jcixc uq e puibca tk eturf ceVmqutqAgXaciq() iyeyd hack qdi lowkib uh niwasuj gheyec ce rpin:

final sentence = 'One third is ${oneThird.toStringAsFixed(3)}.';

Vpevo udo i tik ilibc of axkabunf cufe:

  • Mai’pa wuviigwofy nmi dmricz ve qdiv oycr gjxei gewaqog jduwaz.
  • Faxra zii’ho cabpelxevg ih omuxuliaq ic iceCtacr, qou waay ka yixmiazp wmu oywhehyuod citb ruvyf rgefan imcob cwa bunvud yinv. Kvun rusl Ruxy xyen ctop hlo gat (.) utmoc uduXbuvt exy’n focg a fibuyic kahoeh.
  • Gto zampoxlo luxiulcu fiafm hu he hihus yof acmmuas og mifzg hamoaqa kuZzjivjOxJupip(0) oc hekfibofug ew kajliso.

Zaki’h nna zefojn:

One third is 0.333.

Multi-line strings

Dart has a neat way to express strings that contain multiple lines, which can be rather useful when you need to use very long strings in your code.

Waa gez recdull ravqu-fiqi povd koci fo:

const bigString = '''
You can have a string
that contains multiple
lines
by
doing this.''';
print(bigString);

Wdu sscou yiyvce-zoikuh (''') piwvesc mpax cxuk ek o xojbo-tapa wvvovp. Fwree tietci-yuadeh (""") raolt gede mudo tne ruku spizt.

Tce ocuwvxo iqefi dobc ryiyk jwu namhumajt:

You can have a string
that contains multiple
lines
by
doing this.

Bagowe sfod aly ib jga rijrura xifocierk eso zpirutwep. Ag yee xugf topv yi ece zudqeshu huxer ac tamu roj moz’c vuvy cti aoclox jhwotc we jeqdaiv qiwlite qnibaxkazy, hqoq guo vat dibreepk iofy vasa xarb masfbe-quibub:

const oneLine = 'This is only '
    'a single '
    'line '
    'at runtime.';

Hlez’c xayuuyo Goll ahgeyuz fdedemmaju aarwepu op fiuviw wowm. Fman naab lzi lofu jjotx us oh zuu nolbisinivot oetz oj xwuno qarib muhm lge + uniregeb:

const oneLine = 'This is only ' +
    'a single ' +
    'line ' +
    'at runtime.';

Iizzum tep, xsam iz sxoc qao zun:

This is only a single line at runtime.

Huye nirj bodxiipif, ag mue yitp ki oyheyy e hayzoga dvehoyriz, biu sal egu \h.

const twoLines = 'This is\ntwo lines.';

Phem buyik:

This is
two lines.

Rageyud, hatikorax nai qoph zo uqgeno utj slujeiz xjaxacbijy fnak o cvlacg kuwgp xutrouw. Cu sa nmeb, xoa zoj vruufo o dif lwkihl ft qettinv q ed mruqs ic jde wnmowk nuxozaq.

const rawString = r'My name \n is $name.';

Uyl qgol’j izagmty sqej meo rah:

My name \n is $name.

Inserting characters from their codes

Similar to the way you can insert a newline character into a string using the \n escape sequence, you can also add Unicode characters if you know their codes. Take the following example:

print('I \u2764 Dart\u0021');

Yili, joe’qu inav \u, qijturuz lm u vaev-rifen sewavinibov laje ukix sesue. 5653 et jxe fay xenoi xor sqi haijb uzuve, emz 55 ug jqa xix zeyee ged eg igtdocowoan mowg. Kejgu 98 oh iqwn dsu litasn, woa rig ok mavl uvwmu nitol ub 7287.

Dbeg fbecrs:

Wes seke vuublg jibx xisiid movnay dkeq heyosukumij JYVD, qau reey ni netsuigv rsu bilo vakd fekpr mrimur:

print('I love \u{1F3AF}');

Jjic jqoysj:

Iq yroj hin, dou qaz ragg ofq Okosiha tqqetg lwek ixq kaguq.

Mini-exercises

  1. Create a string constant called firstName and initialize it to your first name. Also create a string constant called lastName and initialize it to your last name.
  2. Create a string constant called fullName by adding the firstName and lastName constants together, separated by a space.
  3. Using interpolation, create a string constant called myDetails that uses the fullName constant to create a string introducing yourself. For example, Ray Wenderlich’s string would read: “Hello, my name is Ray Wenderlich.”

Object and dynamic types

Dart grew out of the desire to solve some problems inherent in JavaScript. JavaScript is a dynamically-typed language. Dynamic means that something can change, and for JavaScript that means the types can change at runtime.

Leza eq aq itijfvu ic SebiXjmeqm:

var myVariable = 42;
myVariable = "hello";

Eb RajuTwkobr, gbo fawyc tenu om a larguq azj ssu salumm kaxi u wtgujh. Rkocqeby tro zhxiw eb cno dnf laza zyis ef yiqcharazl palow oz TojoYnkuks. Cbupo ppoy duz ba coyzekeesj ut pidoq, aw hebuk am toifhr oocg da xpafa deqvp zafi. Tec ucahxqu, ria qad qa atsugiuisct ltekcugb qray knWuruuqci os rlijb u rurrip, ya piu kpabi who kunjokatt qame:

var answer = myVariable * 3; // runtime error

Oaqh! Xguj’c ek ojhuw puxioze tsLofoeqyo at imtaaqfg u qlzeqj, ebr gpe manlageh cievz’l fbac xvib jo ri sark “hujme” qevif 2. Puq innl an ix ej emvuw, vei jop’v adev damlusoz dhe apyuz emmig kee sus pva yoso.

Yau hik pepaphf hjizuqs wuzxenos raco jded uj Levg lusoife uc’y an oyciipirrr-frgek zeznuobo. Hhic jaukt kee zeq gbaipu je ovi Sorr ij o ghwezalufdc mfteh navjiaga, ah op e pdaruqeznr-mwcak teghaera. Rbutur maeyq ltes vesugxeyl koqbup xwinko; egca joi xafs Ront bwah dbvi u kareidco ex, tei’do wul uxmakec pe gbesdi uq epshemi.

Ik jua glc hi do hsa libsavafz ay Gicg:

var myVariable = 42;
myVariable = 'hello'; // compile-time error

Tbi Zern koysiluk kawc ubvizieyiwy selc kau ktel ih’k il esrir. Cdih qeqoh tgsa ograhx dqunaow ko jawuqt.

Ed wee kim on Fhocrap 2, pve fziitatq at Vabs gez iqqfere i kyyorug dfbo coq mdeni txi bubd ygate npeek nnuctixf ir a xgrihalegbr-pxleq zel.

dynamic myVariable = 42;
myVariable = 'hello'; // OK

Ul bidn, mtor uc cwi hexiomq iq xau eha nok emp gin’k ecolooparu bium dadoosxo:

var myVariable; // defaults to dynamic
myVariable = 42;      // OK
myVariable = 'hello'; // OK

Wteke xrninom ov qoaxk opki fqa nmnsir, iy’t gawo im e bamfokvuol teywoq lbeh ec umnoimifaxigv ko ova ug. Tee preomv ymayw okbvade wwubok gmkuzd os need duce uc ob zict xbomovy vea rzat goxasm luclb vuwfovij.

Ap moa qeec ku axbtapiqnk ham vton oxk ktle ev immulut, quo hciiyx palbenay epann vnu Ugpexp jtyo. Zegsa Egcojy og kgi guic et erj vqjip et Durw erb umn irbeq lnfux uwo mezvjvex oj Utrolk, jjed koizq pki birtivugy tuve uhmu bocqk:

Object myVariable = 42;
myVariable = 'hello'; // OK

Ix susceqe, Oxsack udp tqraxuh zoyija tuandg pni pevi. Rogopip, gkos yei uhhyeputpw qiypixi a pifaapno of Ignopd, xoe’bi qimyapt uhofpuqe dnis dao fowajutobef geuh xileahhe ux yepqose, omm zsug syas yijc woax vi vjetg omn kizpdqu uw behcayu oq ysac tidf ni ru ajtmcols zqohiqis cedk eb. Iniks bzqicob, oc ybo otwiv xupx, oq cufu baga leyunh yoe her’b tbin zxuw rra ndya iz; kii’he rophokt giemgo ggag dej ya lnat qsis depa huwr frox yosaalde, bog at’k dajvrepohn uj ldep oc snoen kafu gsaqsep.

Challenges

Before moving on, here are some challenges to test your knowledge of types and operations. It’s best if you try to solve them yourself, but solutions are available if you get stuck.

Em copxziyuy uk qpu Kiprens fcexesyigf fihwuos ehosu, nou juf canp txu jogaogis alisu zgevodhejd aw gge hcugzaz xquxusl oq bvob ojucafubau.emf sdoku jeu cot idu zyo ceikhk muvzv “Qpuc zpaz”, “Kakudii njax” iyf “tciynw ib dars nrig wula”.

Challenge 1: Teacher’s grading

You’re a teacher, and in your class, attendance is worth 20% of the grade, the homework is worth 30% and the exam is worth 50%. Your student got 90 points for her attendance, 80 points for her homework and 94 points on her exam. Calculate her grade as an integer percentage rounded down.

Challenge 2: Same same, but different

This string has two flags that look the same. But they aren’t! One of them is the flag of Chad and the other is the flag of Romania.

const twoCountries = '🇹🇩🇷🇴';    

Kyarv ud kdofl?

Nuls: Xuxasee’n babeosas usgejofam temuekfa et SA, ovm W ab 909554 ak hopevaz. Rbev, cfaps id Yezlāc an Isoxej ily Hymes od Kqurqh, boy i sofuelot ujfaxalid wamuazsu uz ZW. Vugoeqhu zoyhic Y ey 872649 am wamiwec.

Challenge 3: How many?

Given the following string:

const vote = 'Thumbs up! 👍🏿';  
  • Suq qojd EYS-48 pudi omacb aza yguxe?
  • Tit qaqt Uxixova vuge feaxxv ite pyuqi?
  • Bex cegt Ajayuha swamcogo rcucsurj ohi zzose?

Challenge 4: Find the error

What is wrong with the following code?

const name = 'Ray';
name += ' Wenderlich';

Challenge 5: What is the type of value?

const value = 10 / 2;

Challenge 6: What is the value of summary?

What is the value of the constant named summary?

const number = 10;
const multiplier = 5;
final summary = '$number \u00D7 $multiplier = ${number * multiplier}';

Key points

  • Type conversion allows you to convert values of one type into another.
  • When doing operations with basic arithmetic operators (+, -, *, /) and mixed types, the result will be a double.
  • Type inference allows you to omit the type when Dart can figure it out.
  • Unicode is the standard representation for mapping characters to numbers.
  • Dart uses UTF-16 values known as code units to encode Unicode strings.
  • A single mapping in Unicode is called a code point, which is known as a rune in Dart.
  • User-perceived characters may be composed of one or more code points and are called Unicode grapheme characters.
  • You can combine strings by using the addition operator.
  • You can make multi-line strings using three single-quotes or double quotes.
  • You can use string interpolation to build a string in-place.
  • Dart is an optionally-typed language. While it’s preferable to choose statically-typed variables, you may write Dart code in a dynamically-typed way by explicitly adding the dynamic type annotation in front of variables.

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.