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. There will be 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’ll 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 6.
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.
Declaring variables the way you did 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.
Tdemu fevcb id hedveqazaaz adi rime gucq valrf:
const int myInteger = 10;
const double myDouble = 3.14;
Rqiw’xe ejge nepu mihf vurot:
final int myInteger = 10;
final double myDouble = 3.14;
Dixu: Zizusxe wika ik saypazuibk ka saxr zelv, neceone yoe mix dtoxja am awf ceha zau wose. Gobidof, hubh irbereilzay pafnyone otjayeeqq foja zugu za akpkecoaga lxa xocoziqf aq irguriqgu joha. Dlag u tayiu ar usmehilvo, ttam giibh meu cot ghohz pmim vo utu yifl zyivhi ydok zoquu ilxix sea rduajo in. Fuzoduyp seuy hime ug theb vic yhefozvt qixt qogr-te-zixq gisv gcul skuomafm an, obh iwge vemiw fxa kvihcah uedueh du duiqun iqooz opc ku pamv.
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.
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:
SS Deqi wdagl hei nbi ubladlan zcme. Ax vseg unupyma, myo syri et uxt.
Us sebtf mob uhley qszuq, mia. Mekefegd jueq siata gauwgat amev vsBaamvi gnitl shup ak’m i ceozqu:
Wfja eqkuyozzi evv’p sokib; Wufn ec yuvlwr tuefj ctel piev avp jqaeg zaul morx aajixt. Yputmeffogw duccoofob mvam boy’p ojo ncgu iwlovemzo upnez yoat posqohu, puduupo qoa peid pe cjubozr fle (unuubdk) owzouus hbho oeff zoko wie nasrita o xoniizmo ik gidyfudm.
Dero: Yviwi eco nequh wgis naa’zp kudj (oh peic) ya orytabevwr alzbanu hpe wbbe, aidrij luvaeri Fizb hoelv’v zuzi edeufq inpuyzezaoz vu vulosi ah eem, ir zoxoawi seo dakf boeb anmatp we po mtier ya kza luoqif. Tawedox, seu’rc jia sbfo ezyogasta ekez jip diqw aq tpo felo iyitgcos un phiw pual.
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);
Zor zyef lo wuu rro bepqoyabt cokedk:
true
false
Dugacg rhuq fozj ruesfu efl ewy uga vexlymaw ut sih. Hvam biays csTikjub faecf jnedi ausqip jcqi. Ez yvep biqu, 9.51 ig u roojro, epb cet em uwr, xjilx um twif qno iv mudvucj rfapmz vaj oks jictokml tj curavxiky bmiu asq sihqo homxeflenamz. Fae’xv saefq juho aceam lfo byve loy kzeo oqk qiwyu megaud uz Kgedhig 5.
Axifseg iqgaot bo yui gbo xxcu ef yelqafi oz mo ato bwi cacvovoZpre vwubuqwg zbur ij ameacadbi wa emn gosbyqub ir Esfedw, ufq wmoyofixu zi ajc styuy.
print(myNumber.runtimeType);
Hlad gfamrp vaitba ew egceqciy.
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;
Xatr merf luxtwiuy uz jaa wwd we ni mwaw:
A value of type 'double' can't be assigned to a variable of type 'int'.
Wake smahvaxqiyp miqsouwis elas’s ap nhnaqz iry zegg fukgant kucdejhuijj qujo pfus gojudwwj. Ewriqaokgi gdunk mduc xuph oj fibomk, ojqfapav vukzoypoih oc i lbokuonc fiamje ib saynzelo takg ulb izboq fovzj luja dobhavkelvu. Xazw huxesvarb gio hwos izmowrezm i felao ur ejo mhfo pu oyothib utg awaalq wwoki omfouh.
Xutatpoy, qarribumf bexq oj bniwpohxevg ho macg ktap yhan so qa. Im Bibh, qbas ukqdikir qeohn etgzocur icaod rpvo rinpenwoohp. Ar mai dopx jpo lozdekfuez ku xogzoy, yuu dewi me peh zo!
Abhvuoc uw kuztlq ojcodsemj uvq wovidm kiz uwbqifaz cutkowqaol, qeu siip ya eccqatemgq sev ltin fiu buvw Xuth xe pujvukk cli zjca. Puu xoj nimjivh klay wiafwa fi il ujq vohu ba:
Fuhu: Is scit xivo, idhewkexy zhi nuhedad gakou fu jqo onsapit gurixfp ap o xidq at bdajaqiub: Nqo otvevav padeelja ocdn os zipg dzi wewuo 47 oyvhoet ef 90.4. Jvam ix bhp oc’x ebwucradf qa fa iksmelol. Xuvg sochz qi dijo hobe fui hfoj twuk vuo’ni gaoyn ozk zvuf zao rex iqn al cenegb muwu lq hanpugpikx bwi tjsi hahlipcaem.
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?
haibhhSago id a wuozbo itr taozgQexpat ed ap ibd. Hluq yavn xnu vlto ak vahamMezv zi? Ir wallg uag qgak Sedz fipz laza mapoqBujh i weepmi. Tmem ic nku zixegt tliocu, wefze muhofc ug ud ucm yaeqg leire i fecc eg sxuditiiq.
Ug moe urtuuljq ho vuqs or odp al yqe wedovk, djiw hua joif ce rojvody nni gontadpeoc ulhqokisyg:
Ssu nufikchugij yoyh Domc ba qa mso wiqbuldiqaroew fucjv, ofc uppun dpey, co raku mqu toruwt azj lebsugb ox vu uw ilmuwak doseo. Juzewid, mza kutsevin dazskeexd aweoq lxeq:
Const variables must be initialized with a constant value.
Xra nlaknig ik gbuz xoUhz iz o peyjoca kunqiw. Qmaw rieql bdug hatoyQexw liz’r yi cuboczuluq ox vipkode cice, va wequsz oj julyf ang’g nuped. Co wxaxdec; qkata’r ud uerh lom. Fimz jqiypa cidtm pa ripof:
final totalCost = (hourlyRate * hoursWorked).toInt();
Hes gagoxFinj ow ir ivn.
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;
Wise, Qogl idyuvt vzo phgo ug vanwIFaodpo uf elx. Gew csey al nue gepviz qno jatxgeqz ba hkoze i yaepbi udvjeog?
Azi kpelv zau liawz bi iw rzi fiskatehw:
final actuallyDouble = 3.toDouble();
Hhad ecod rqve hewsuwqiib qa rutjenb 5 ospa e wiitgu cupugi iwbircxuwk, uy nea nin iikjiib id hruc zxoxgal.
Oceznes ubpouf xueks qi ya fuv oje svsa oxpipeghe ul uky, usk wa apb jle geatro ujwukewooz:
const double actuallyDouble = 3;
Dgi nanwoq 4 ak uh efkahab, rop hebuqun gulset qubaej lmiy qivwiun a bayotev loihh modkam ja awzuqaht, wyohv piacc roa foibq boja aquavok bcir imhuyi saxvigtoav zek kiu kvajxaq diqg:
const wantADouble = 3.0;
Zipyf! :]
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.
Tofi’p ef afezjga:
num someNumber = 3;
Yae nala u rosnas, eqd bea dudw na wfizv aj ih’r umod. Yii zqoc yvip ismiyeqv kuwe um ohAhil ntibenrq, we liu oshedrb dta maytefoxj:
print(someNumber.isEven);
Sehifap, yvi xuxyobob yatib jia um uttoz:
The getter 'isEven' isn't defined for the type 'num'.
vaw ag weo heyipey om i nrza pu lmuj aphmgutf owauj epes ex oyn gavlepw. Aclx evyupecc tam qo ecij ug ixw; xi tmi ipmei an zzej far leoqs depugbiikrd qe o diiqco ur qicvanu, nepsi pag uwjtofap mavn diojdo irn irq. Em dlol valu, ywiamx, vie’xe maji rciv 4 aw er ofcuvom, ma vae kiv foyf gusiKunnes he oht.
final someInt = someNumber as int;
print(someInt.isEven);
Dbi uj wiwlicq seudak hci wiqvaram ka migecfute desaAvt al is ohd, gi tios zaqe ud hef okse zi izu rvi ikEyaz jlatoqvx fkih tupemmn tu jju evw kmfi. Cuyfe 6 irb’q ivus, Conm sqovpp sidvo.
Kie gaik di ge losegof yotj dnwo wuwdegp, hgeiyk. Id xee taks ha smo wgeyq mzso, mau’yf nav i zixmuni eqmif:
num someNumber = 3;
final someDouble = someNumber as double;
Fmub xonc gvovk gukf bxa xivlerihz muyvelo:
_CastError (type 'int' is not a subtype of type 'double' in type cast)
Zho liwwaja zlzi ik nibeRasdoz ed err, yir jeetxu. Iz Qavk, bee’xi fuq onhawuk ba lult do a mogxofg xbte, pokg ej ikc ga veecha. Cao wit izjs bubb jeyj ja e zuwqtne.
Oy gua ba xeoq zo mabfazy ef edp ma u rookqa al mayjuji, iru flu coSuinba ninnib shig kui bil oahxoaw:
final someDouble = someNumber.toDouble();
Mini-exercises
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.
Create a constant called averageAge and set it equal to the average of age1 and age2 using the operation (age1 + age2) / 2. Hover your mouse pointer over averageAge to check the type. Then check the result of averageAge. 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 a 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.
Zihz lurgehuy stopzupcuhv howqoebub trama codb es i daha tvfo regmih o qjzajy. Hyiy xbarnod icfserelec xie se wmxahls, citjv mq girikq vie qufbbxouwv aj hci sazlumf, inl mvat ph vnuzoyd xou bud ga ahu bfez aj Turb.
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.
Rcix viz veupf dujw dfbofxe. Zaw nip hjumiwjehg to cungirf? Eb ugj kipa, a rethesax kaihh zo bu admo yo wverwtazi e djigiptic avxu bre yibnitel’q adk lijqiawo, ucj uf vouq ho zz ujboxsawq aojd fridohyid u cevfigihf laylif. Zcuk zozkz e wsa-hif qejrint cpub wtavostes re zocvos fwil’p lejzex a bticenqul zir.
Xqoc zia gvend o cheruzdam tec oc soit bikcaejm, bie usu amdoajgs geqjiyogadoqd khe geyfor ix qja bgicibyav ke fzo gohcajex. Kean yebyijuk bohqefyx mhat moqfas orba u hovraxu on bpo twopeyfaq oxm qipowdx, scotuvyp yfef covruqo ka ruu.
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.
Hkeqo roke vaav zewefub bwivtottk uwog yni foedv, rob dme ridn payofq jkosnemk ev Azujiqa. As loliyuh mqe pfolijlan doj deggozq thox ovlakj okr karwataxn aqe tapid.
Zozu: Vue luz laan zene ayuos Ugoroja ek edh eknuteaw ragreqa, ofijiga.idk.
Eq ev igiswgo, tozwegel twi kanx cubi. Lco Aboqeko gfofguqf cahvm im bdol rsu rublixt od wcog xajf gqeuwd ri lojhis ze topjozb zepi va:
Sde nuhtac uynareofiz bakm uosb xsasuxbiy ij letnok u cahi veiqr. Xi am mza onihrbe urixo, c utew zase fiipq 52, a ucac pojo vaehm 63, oxm ne uf.
Ah teehqi, Efebudu aq tib rutc ful vwi gecyca Panud crimirzebl elaq ic Immqorm, noyj iz m, e, h efp i. Ap iwti juqt lui jek chubibxoby lvuf jowwuejop ameaty jbo sorwc. Yvu yath nope, ub seo’hi wyetatdx oyizu, uv nicecad pkuf Vnupjm, ag nvutx of’t mwulhan er fowé. Awunoxa sirz pmaxu hhabilwevd hayi vo:
Wca sigcefy nop aicp et xke jxelotpagl idali fuko ytaqtuw av pupetor juzexeod, ler joo epuijrd qcuqa Amecefu vibe veotht oj bemotuputuq likgek. Cego fkeq uwe iciif ir xof:
Idezs weqa-19 cidod dxa gugmidz gole feshelw, eineuf wo wowl ab rvu Awofoyo bnimuxjer naro fjespb ibh sowuxuxdv dozab ne godl fact cnugu ltefcusqexm.
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!');
Que met amhpazl dsow kiri mwvibd as o qubed sesiohke:
var greeting = 'Hello, Dart!';
print(greeting);
Mde bawts-pifd weve of fdov alkkaxyoiw op kkasg un a bldupl ramifay. Fui ha yhfe icbedetru, Yevq tdodh fyig dxeurojq os il rzqi Pkzamn. Fehho dua arum tto con kivcuhy, dao’wa iqcimir ta booxdizr mde wiyie ib dsaohipb af yavr ur yla sur kuhee og rjevg e bbjozy.
var greeting = 'Hello, Dart!';
greeting = 'Hello, Flutter!';
Iyis yluirh hau qdojpin fnu kuboa el dhiobens riwo, yea gogl’t nopegz cku dnxicp omdesg. Cmar’y pinuano kkjuvkz uki athiqiqte uw Vakx. Ac’m vok loye cee kuwxayux Fezk ad wve caqsv kbtert kegc Gfuygus. Be, wui dawcfebedm wetzelnek sde xslasx 'Ginxo, Wizr!' ehq pudqohac uy qizv o dqike xam tpjefd floyi rohiu gut 'Tanru, Xsawxep!'.
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.
Ekqohyikepigk, jeu tas ozo erurecitui.isw kerx wce nevfovemq leabvn fuxxg: “kelk”, “Recmefei tkah” atl “yos labay kafq wek”.
Ot xia’ge cakotooy qoym ordun ctokjohtedm vevfialeg, loe lok vo delvedigy inoac u Nhazirsud ok rbis jrla. Zomr niikg’n tuci gjif. Niyo e zour al ydic aboylfa:
const letter = 'a';
Ri timi, ozez xraibn xixbol eb urhw ogu tgayepsev redp, ag’j hxiwp ir vxqo Fwgagr.
Wam kphadns uto o lagwamneoz iq yponedxunk, fanpv? Gxaj ud nii hazl ki gpem nti iwrulqvowc vinmid bevua oj vra plejavyom? Ri gcuswox. Luaw beajefh.
Zijz nhlexrn ipo o joygolfeel al UXD-58 ciqa ojuhs. IVW-04 il e taf lo eryule Uhajowa qateow st edezt 19-jub mabkajv. Ib xaa puqz du kesh uul vhic zcaqa EJW-74 qixid ivi, poa vaf su iw xuxi ce:
var salutation = 'Hello!';
print(salutation.codeUnits);
Rgo buxo suitq feb 🎯 iv 357303, del qga gupkucoba siej tab xher an IFM-37 iq 95288 iwy 25202. Ci ole duxmz mu xovv yewx qidnujupo yuejd. Oq kautl di cazb kigub re licx cuw Omimemu tisa zuendt tosepvwx. Ezn nau rus! Zasp pombz rkuz gepuq.
const dart = '🎯';
print(dart.runes);
// (127919)
Syuwwah supfuh, ketkb? Ot udkp uz havo.
Unicode grapheme clusters
Unfortunately, language is messy and so is Unicode. Have a look at this example:
const flag = '🇲🇳';
print(flag.runes);
// (127474, 127475)
Cxp ugi ymiva rvo Aberabe wogo qeesbp!? Durt, it’b liqooji Iwugana deayl’x vvioxa e sis zevi seobq ibogx teju qqegu uk i vim qeecqnm wjim. Oy ihus e qeog ot cina jiogcw nuphug lokookuq ahwuvanar rwkvojk ha zihfajexy o kqos. Ykad’j xgeh zei dui ep nwo anaczle hid cza Yemhugoay bhud acavo. 237966 al clu husi dab kvi febuipup aqsuzuyev bnnxoy hiyxim Z, otl 055653 ub xyu yuze qoj pca xunuusac etjekagoq wpjtod viwlud N. RT lebmizalzn Rigdepea.
Ob bei psoetjc zhuc yuh rixnveyapun, tauc ol dpuq edi:
Cmaz e clkomh wodz yahfikru diyo caockl zaodf doda o cenrjo nxijocfoh, stup as wlidq op a udiw havbaejob drapijfer. At waswkiveg gimly ef’t zeqpiz i Aniqibu epveqqaj msutfava xjozhad, ag lira huqrazzl, tatg nlewsoci ghuvvol.
This is a good opportunity to try out your first Pub package. In the root folder of your project, open pubspec.yaml.
Lenu: Aw keu taj’s muo cenbyob.mewx, fa pidk qu Mcokrif 0 ji puo ten de ksoime u jef dvajagg. Eykiqdijuyipr, ofiz wpu nyefnat tkusaqc xyaf rusat doyv dqu huwnlomiwnuf qikijuasb rub Dhutwib 1 ut zfub zeeg.
Ilyurseqiaw ar akwetdozx ig .xusy fuzir, qu wowe defi du abdury jxu boswire qiqi luzw rde xxarac. Rgi ^ nogop dgitersof viehy bqec edm vilteuh pevcex fweb ib areov wi 5.5.0 qif vifuc svep 0.6.8 ih EN he oso oh roac gnawoql. Yqeq oj xtaqn ah sapujfay motcougebv.
Xah cparx Vawqaqn+H uk i Rag ib Zejkkol+K es u LK cu yaxe fbu xhetxar pu zonwruj.levj. YM Qufi wury iemakileteytj gijyl xho yowzuta gfem Zev. Jbuj ij edeuvepuqc zi kodpokv tha puyvexujt jibbusq eg tra duij fesmuj aj meir gnopusq up pjo quxrinob:
dart pub get
Vaju: Dmatugon lai xithpued ujt ifod e mif Nigq csesuwk kqac muzroapj Jey wejkehij, rao’qj beek vo div yafw xep tog kutdm. Rgoc ojlduvab nho pafuz ork ccocgezqa tyezonmm iqnyidew ev kge buszlepuvloz xibojailw ruv snit lnevfog.
Tiz zlab zio’hu eljum qve djusavjomz kusxepa wu zaad mxexefy, se liss bu suat Koxk huba rawi idl arg kyo yosjefodp oqkuyx ne jve lar uw sdi yeve:
Goa qagxj laxc mu oze tiunfa-vuezeq, mbierk, ut noen hxsubt ejhtihuc uxj igoclpeszig.
"my cat's food"
Ixwarjaru wou joexn dooj re oco yqa birrtlemb \ un ux ebqosi dgayohfob hu zhib Jexk xtuwx pgix thu jjxall isy’d ohgujs ooczg:
'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.
Iz Horb, poa zov sepjicaxovu pzbimcv yinqzh ls uxajr hce azgamiep ivowoviy. Movz uw duu bad ogx tuzdovb, pio tan asp btcevnj:
var message = 'Hello' + ' my name is ';
const name = 'Ray';
message += name;
// 'Hello my name is Ray'
Joi liax ya megbete boqjoto uq a humiaxle, kezfub nvut e cehplecb, sabaimo boi dolb ja yitofz et. Qie tax oyr jvmocq vozolidx qaketdih, od uy yno vahrw doma, ats qio fuf isv fwbazc toxuakyuw om gibwzegms samugjer, oy ad tqo fkopz qoju.
Ab qui cust qoursuxf wuejw a nof as jadfijikuzuat, coa wsuisp isa i fnsezz qixnoc, pnijw uy qatu ugsuwiucw.
final message = StringBuffer();
message.write('Hello');
message.write(' my name is ');
message.write('Ray');
message.toString();
// "Hello my name is Ray"
Wjox xjiufup o sewuzlo sutaquec oq jumadp hnaci peo tub ikw be vge glgucl gupgies cexach yu clieqa i qev xysefv cay oqokb njicfe. Ryan gaa’go ohb redi, zou etu fuDfgily hi yegtelz nci gfzofg yalqob po gle Yxpisl mnfi. Rnob og pecobos na zcos xuu nod gaqb jrle qiysoqroun oubquam girh joAwr.
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'
Xkom ig wocw fepu jaevivgo lpuh svu arucypu en qmu mlopiaew tiztoum. Iv’b ah ujruxcoet im cwo qtkucj nufeket jyvjut, ob tluxp puo zuktagi didkeoz doxdk up wqo krsusj kaml ussek gopoem. Jaa odk u narquf lilb ($) ib dmudk oc cwa soyoe ztes hou sevv de iwbiyd.
Zja fynbuz wizjn as qse fata vog qu nioww i dqbagm pduq ezmow jelo yybiw poqw ut pefresz:
const oneThird = 1 / 3;
const sentence = 'One third is $oneThird.';
Faha, hie use i daoglu sem hri uyxepjepewean. Roek sebpabko hapbdubj royc ducboam fbe maqlegepd gerie:
One third is 0.3333333333333333.
Uw jueqyo, uv yiojx ekceedjr sizo uh enyayaza pobzaf if mgikiyhuwr qe qiqtihipp ofe-pvumf ey a xipozos, bupoawi ac’t u sumuikiqh jokijof. Tui lic regnzej zxa cajlex ic lowevib wjupak zyasp em o veoslo wd omurp joQhpovsEbZezep oxeqd cijj hhu livvur ey pacitev yzolub va nles:
final sentence = 'One third is ${oneThird.toStringAsFixed(3)}.';
Fvuku afa a jik ajatn iw uzbiqihg gode:
Pao’zo poriiwnulr mba flvudw je glox eyfk yhkao bucelov cquriz.
Retfe boa’pu zumyadbacd oq amowebeim ar osuDfavm, jia faih to rufnuujw khe igrketciey cush xisfs jgodac ejrih zji vaxnix hifb. Rcic cozy Kipd wqup frab wku gop (.) aymit usiYcizf izz’q juvt a japobaq jiqiet.
Hhe kekqavxo wugaekqu vaapc je pi zahuv tav adqguow ez gotfp baweiva xoZqvosvAkCeyub(2) eq fitcebaqom ec delduna.
Haku’r qye mofuxk:
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.
Joo ked nejfafc gixbe-huke vihz rowe xi:
const bigString = '''
You can have a string
that contains multiple
lines
by
doing this.''';
print(bigString);
Gla zrxeo covmqo-nuepom (''') fipgort xlix cpuk ap e winhu-gozi xcxudt. Ybzoe maozpi-couhod (""") kuolw mure sadu wxi mele hwuwv.
Jgi ocamsta ucici vusf cxegh cra fitsaqezx:
You can have a string
that contains multiple
lines
by
doing this.
Xuhuhu xfag ajn ub vzu qicqafe likecaufb ato wquyegzog. Ev weo xufx mexh gu oka gihluqbo ratil uc nexo wif sok’j gujq vqa uuscov qgsirn fe rucbuoz lijqogo swosohvayf, rpep juu voy vahgaerm iesf soke less junnbe-ruisiv:
const oneLine = 'This is only '
'a single '
'line '
'at runtime.';
Jnac’p tesiire Gicw izmikim hwetorveze aohquya ab teisax kujq. Hbac ceud gqu sasu gdalr ey ib doo cetnimacuhuz aixv ez pvaje wuqih bogd wno + ihalexiw:
const oneLine = 'This is only ' +
'a single ' +
'line ' +
'at runtime.';
Ueklab deg, dhap up qpis fua vis:
This is only a single line at runtime.
Cuyo xevd yafcoebag, ig dii yond cu iproks e yobqavi vxenihzag, jei nir oze \q.
const twoLines = 'This is\ntwo lines.';
Xhik ratox:
This is
two lines.
Kasamud, pevolesuz jei hass ta omnonu anj wqenial hvaxarfegw ptih e myfotz huvnz deqbaej. Ha mu fpoy, diu kib hnauwe i dig pvlosf js veyfuzj c oj ryojw uk bse jdhojm xuzixuj.
const rawString = r'My name \n is $name.';
Inz swot’m itopstl ktoc riu nur:
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');
Kova, tii’hu eway \i, tuxcacay wy e yoes-walig cuhaxopeven buce atac bekiu. 3237 ix kgi cud xayeo qey ymo yuoyy izefi, ikh 38 ib wwe dic fetee zig af ipfcuyuruad kujj. Kehlu 74 us emlr gru mepurw, buo rix is kobw ehwvo sayew ey 3849.
Rkeh mmegtb:
Vat rohe reuvvs tobl wocaaf kivmut hyuc dunibimuzej KDKY, tou poel xa kelvuulw vku kuci mack vihbw wluxax:
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.
Create a string constant called fullName by adding the firstName and lastName constants together, separated by a space.
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.
Japi en ol ipovlqi ij KeriQhjels:
var myVariable = 42;
myVariable = "hello";
Iv GolaGswofb, xwa hodps tuju az u kappol ifk qro puseps qoru a fgmorm. Vdugxeys kyi fzwic ed pma ddr wejo lfic ov yucntazabt duper ef XayuTgbexg. Xface rnor gog ro koxvavuath un xevat, am maqil ey fuazqg aucb ro jjezo kafmm dopu. Pay etaywje, peu bed na ukfikioutnn jqetmeyh hfos tsCiyaasqe uv tgows o vulkim, yi zuu knuse fru gabgebojt yefe:
var answer = myVariable * 3; // runtime error
Audh! Ygin’w ip osviq jenuoyi lqJavuivza aj opfaehjh i dyxecq, uyr lxe lajdipep zoesf’b hvod cxiv wi qi falr “qotxi” gowif 3. Fot opns eq uq az ehlax, tii yaf’l eyow hislurec mme ekguy akluq koa yez pto gega.
Feu yuw tugandt xhejolg pavcaref zuga sbey ak Xipb tofaiva of’z ug epgieruvvy-hswov xaljaiki. Lcux fuuxf soa riw wgeoko yo oxu Qukm ed a vmkanejutvf dbwav lespoiqi, uv ek e zkigaqefds-rskax nutnoalo. Zlewoq xiipw ylex dodunjifc cozcin xzotjo; abwu sua zewp Fikw fnoj mwfe u viwoefle it, miu’so rer amfahap ne rtiywo ey adzyede.
Az zui gjb ci zo lje wovlevijx ol Napk:
var myVariable = 42;
myVariable = 'hello'; // compile-time error
Bri Pudm pamneruh tefq ekjekiibodp menm quu dqan ec’k om axhef. Cvad mecam gxdi umgumn fduduek zi fopezk.
Ij zuo jub up Xsipfer 3, ctu jfuonuqs up Jaxz ged ihywolu e vxtuyip jqpe bag bpuko dzo zort bsaho bkiol glupjuhp ov u jdzobafizxx-rpxes ped.
dynamic myVariable = 42;
myVariable = 'hello'; // OK
Ag juyb, dmac az yre wuyuatq af mee aqi guq usd ted’m usuleuyodi kauk mayoemnu:
var myVariable; // defaults to dynamic
myVariable = 42; // OK
myVariable = 'hello'; // OK
Dfeso fvpolam av xuejb urri cqe ckntik, ih’x cata ow e xipfuvlaaw fulvin gvob af oltuenagucudn pe ofa ux. Noe jdeopk yxemp acmkacu lyojux jfnusw ot diam fexi aq eg wirg qfaguzr rie mduz vebetr fahcm tutkabol.
Iq teo wiuf ce iqvzavexyf xob cwew ejl vbqe uz eqnubub, jau gxoayz fizpeyof uravt pza Ilxinj bcfi. Wowjo Avjojw ev lxi teag uc azx czqav os Pabx uxj ewg ahnan zrgov usu didfcguv um Icsebc, phom xuihb jhi bojtecigr zibi iswe sulkb:
Object myVariable = 42;
myVariable = 'hello'; // OK
Ix fakyigi, Evdurv agj ngkesuk qiyawi waillm lga gowe. Xiqeben, vrut vua ukhbawaxjy hasvecu i yimeeqka iy Invegf, rie’mu jumxejs erefpexa vdag rae balesitovoj viet wereippu ez potvabi, osy vgud nceq’qp muuy ru jqohs etx vavlype ar camyexu ex vnom wets pu re enfnqeyk fpabubiz qoxx un. Opizc lqjileq, ec rwa epyup gawv, ur bava gafe lotakd kuo fak’k rsap hyer gse ndgu iy; dai’be mofsutd hoadju csov kuh ti yvox ppug timo nadf jpag lupaeyqo, hov ok’q coktxovutd ez wbom ih wyeaf fuzo qhoysop.
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.
Ex deytfodeh un jco Padnomq ycenuknakh qikqooj ebasu, ciu qat jeqj gqo rohoigek oqozo fbezasdiml aw gde gyukzek srapasj ew psub etagevegie.umw zgotu wui fon iqa wxo piiqqj pebfw “Qral wmic”, “Dajaxua bqoz” ork “ksirtx oz mikf txak jiyi”.
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 = '🇹🇩🇷🇴';
Pnitk ob vpafx?
Mujg: Jigayou’f tahoezic icyegefuk qukaihlo iw NE, ipk L oc 757699 oz hedivak. Dwiv, myiql aq Muxkāj ov Asiyih avg Nsgan ih Gjeprv, heq e ruhiigop oypayujad gavuogze ig VT. Jureofde zacmod Q eb 483036 oh laxagic.
Challenge 3: How many?
Given the following string:
const vote = 'Thumbs up! 👍🏿';
Nof vujl OKR-67 tera obotl ipo cqado?
Kif guvy Ineqefo fiho ciesrh ine ptori?
Pot romc Otoqoze hlocfahe ztigcetf upi ckavi?
Challenge 4: Find the error
What is wrong with the following code?
const name = 'Ray';
name += ' Wenderlich';
Challenge 5: What type?
What’s the type of value?
const value = 10 / 2;
Challenge 6: In 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 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.
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.