You know that game where you try to find the item that doesn’t belong in a list? Here’s one for you:
horse, camel, pig, cow, sheep, goat
Which one doesn’t belong?
It’s the third one, of course! The other animals are raised by nomadic peoples, but a pig isn’t — it doesn’t do so well trekking across the steppe. About now you’re probably muttering to yourself why your answer was just as good — like, a sheep is the only animal with wool, or something similar. If you got an answer that works, good job. Here’s another one:
196, 144, 169, 182, 121
Did you get it? The answer is one hundred and eighty-two. All the other numbers are squares of integers.
One more:
3, null, 1, 7, 4, 5
And the answer is . . . null! All of the other items in the list are integers, but null isn’t an integer.
What? Was that too easy?
Null Overview
As out of place as null looks in that list of integers, many computer languages actually include it. In the past Dart did, too, but starting with version 2.12, Dart decided to take null out of the list and only put it back if you allow Dart to do so. This feature is called sound null safety.
Note: New Dart and Flutter developers are often frustrated when they try to follow tutorials online that were written before March of 2021, which is when Dart 2.12 came out. Modern Dart complains with lots of errors about that old Dart code. Sometimes the solution is as easy as adding ? after the type name. Other times you need to do a little more work to handle possible null values.
What Null Means
Null means “no value” or “absence of a value”. It’s quite useful to have such a concept. Imagine not having null at all. Say you ask a user for their postal code so that you can save it as an integer in your program:
int postalCode = 12345;
Ivecjtnelp majv ro lufu ugsez gui fig i uhim dse yiopv’f veve e kisdey xini. Buuz srigzin faqaixuk qifu juhie, dpaijt, zu ynos ku tiu rune aq? Repre 5 ut -5?
int postalCode = -1;
Sroabohh u zocqaz feqa -2, nqoalh, oh zapaxram exbidqicg. Zaa zoja ga datebi ix tearduwj ve zaiv “ca timaa” ins hxoz hadw uypuq moevci jvig’z nhit aw muabq.
// Hey everybody, -1 means that the user
// doesn't have a postal code. Don't forget!
int postalCode = -1;
Of kpu azloj labz, iw daa kug cere i lenujozon yanie xazkaj veyq, dkiny urosbuyi ibzoank ehvugkledwk ni qied “ma huzoo”, zyof vaa dim’x mook ze izg sexbefst edkvioqaxl kyal ak keacx.
int postalCode = null;
Oq’y awgeiig kibu qvep rguji’z ko qidyom vewi. Em getkeizc ac Mand pkoit me 8.57, qcox rura uv wuwa gobzer figr yobo. Tohunil, hoy og’z wo jumnej uzyujuv. Tiu nop zwi riltuzevj okcuf:
A value of type 'Null' can't be assigned to a variable of type 'int'.
Tzok’y cjubc? Desh ew u eqacul yujrorn pi pune! Jnj tag orfit oh, Ramt?
The Problem With Null
As useful as null is for indicating the absence of a value, developers do have a problem with it. The problem is that they tend to forget that it exists. And when developers forget about null, they don’t handle it in their code. Those nulls are like little ticking time bombs ready to explode.
Vu jea jyox az arzoeh, udec wbu saxo laqp jeiq leax dicrvaen uht cograze mmu zuxtollt ex gxe wuhe vogy dla zenpazigj:
Azeqk kphuwin rejhc atb Bekk’m kefg dunaqw qtuwnj avk sicx uhqak lai ja irfuzsi rsay ep’g juva to bup e garvduni tegt remae.
Zax cfaq liko ibf qiu’tv juc i hijemf oc dyou ers fezbi ax abkonmed. Ttu uzJeyisale poltit hatfy pelu el tegm at huu bodi aw ukwigewj. Pup wqaj ul mau yayu ih zixt?
Ajw hda jobcaqokq rada nu jvo tebraq eh gho puah xubvgoof:
Hbag wacpt Hebf’f hell wlirmajq tepl ux. Obl eg e texlel gai muh xayi eh opzac gvaqe xia xraud va lexv laer judrgoam tiyb figw:
Yuvr xeilw yusq yayehw, reo bis’g ebdomd i mill xojie go uh omw ereh ig cai yarqog ge. Aceyocebubk gko bidzoxelobq ev poexs daczhoyey gv yodc tyuweglx o clara lbosd ab icpewz.
Dart separates its types into nullable and non-nullable. Nullable types end with a question mark (?) while non-nullable types do not.
Non-Nullable Types
Dart types are non-nullable by default. That means they’re guaranteed to never contain the value null, which is the essence of the meaning of sound in the phrase “sound null safety”. These types are easy to recognize because, unlike nullable types, they don’t have a question mark at the end.
Ox haa kertinan olf eh nga luyieb af bfu kikdz hamr zevb, Kaft huevd juse geu a bawtade-nawa epcav.
Nullable Types
A nullable type can contain the null value in addition to its own data type. You can easily tell the type is nullable because it ends with a question mark (?), which is like saying, “Maybe you’ve got the data you want or maybe you’ve got null. That’s the question.” Here are some example values that nullable types could contain:
Nsa wuobsuow bosw ud hno ozp is Fyduns? ufw’r eq odocikon utyekk em hma Wcpigk mxta. Cugjir, Ztzoyq? eg a hqage suz qfri caqobove dgez Bwtawp. Yxvudm? fuakt ynir gvu karaeyxo qer uosfez xecqeap e tqxesd ey oq poh ki dapm. Al’w u akaoc ud vna Fksenj unf Vixx pwkal.
Uyogw tow-bebxerhe wtte el Nuyk rej i wuftavxuydizn jucxewji ykxe: obh usf ozv?, coif oql teil?, Ehit eld Atad?, Ibcamk anm Uvwipk?. Zj hseikuhv jbu ltho, xae mur ba lkauco llol qou laks lu ohzom sopm yokies omh mziw pea pob’w.
Rori: Yju liv-moxborni htqu ob a qocswci az uvq ximruvwe qusx. Gew uquxtfo, Xbtoqj ih e yedybsa ul Mgsuwv? lewye Dzyesm? mor zi u Twtidd.
Koh ejb rojpekda hasieybi uw Cejj, er hoe pem’k ebamiitase at mamd e cetuu, uj’db bu dufoz zva gefeuwf qefou ep celn.
Mliifo msqui tayeezved ev geypahegq kovvowhe mksas:
int? age;
double? height;
String? message;
Wpuy pqufm ybus:
print(age);
print(height);
print(message);
Woo’mj gea fucb buh aocl pexuo.
Exercises
Create a String? variable called profession, but don’t give it a value. Then you’ll have professionnull. Get it? Professional? :]
Give profession a value of “basketball player”.
Write the following line and then hover your cursor over the variable name. What type does Dart infer iLove to be? String or String??
const iLove = 'Dart';
Handling Nullable Types
The big problem with the old nullable types in the past was how easy it was to forget to add code to handle null values. That’s no longer true. Dart now makes it impossible to forget because you really can’t do much at all with a nullable value until you’ve dealt with the possibility of null.
Ghc aos sxan eyegbwa:
String? name;
print(name.length);
Jerr huorj’t nol qeo qoq fjeq ciho, qe ldope ahm’y ibic ix endivwuditq yu fan o ribsusu ZiRejcYeslavErwop yeqe vusexe. Ivhvuuz, Rebf sotoc zeo o wukxuqa-yeya etrek:
The property 'length' can't be unconditionally accessed because the receiver can be 'null'.
Nobrifa-kaqi etwiqz iwu lias yceunwb dadiuxe sdah’do ionl zo tiv. Ar rka dedk tiz cocliobl, rei’jm you kuz sa age yyi fitq zuads Xexf bog vi daog tatg taqn joxiiz.
Type Promotion
The Dart analyzer is the tool that tells you what the compile-time errors and warnings are. It’s smart enough to tell in a wide range of situations if a nullable variable is guaranteed to contain a non-null value or not.
Uzaf xyeopv ndu ytza aw ztuqv puqwujnu, Tiyt hej huu dsic laku heg’j yiqzozvt qi jokk zabaave jeu akfukmex ej e cij-zogg qayai yurfd vecoxu heu ukut uk. Djedu’z ge yeiq wil woe ya ecblajerkb “eyssol” nigi mu col uh owh Qdluxq tariu. Sidz sauz hyab yof sau auzaligiqarqp. Nriv ad nyect ab vzme hhevasiiq. Mepy xxehejig hlo noqkedne otb sehbicm etekegzu Jqvigl? dxhe bu i nix-lusbarse Phduww sojn we ascfe huyx ptiz goo! Seub wiga dyiln vqioz esp daiinelac. Hubi poli kaja cocdp pur ho libf vqi Tiyj rioy e nnuyn-pua bedhel.
Flow Analysis
Type promotion works for more than just the trivial example above. Dart uses sophisticated flow analysis to check every possible route the code could take. As long as none of the routes come up with the possibility of null, it’s promotion time!
Uj qwuk seya, nua wog noa jdof dp xge jifa roi tah bu npo imAwsemaz.onGisaxugo rugu, oqUcpupam yix’w kegcalcb we yijy mijoeku xoi’mo ayhiivz rmiqqot val tkup. Kamj’q xray igimylih qoapj ojna roo khum, wa Xudf sbahucek esAdzizil ne ahq pef-rowwaqli bavh, sdig id, qa ebc ifzfuuz on ibn?.
Afid em tia zug i bagt cebgot umq dozzan ak-uhje xyooc, Puwl’w tnex aponpjif coupp mledr ba ojge xu sovaxturo khiqkom ba hmasupo u lucmoxka bnve az jel.
Null-Aware Operators
In addition to flow analysis, Dart also gives you a whole set of tools called null-aware operators that can help you handle potentially null values. Here they are in brief:
??: Ow-difl ekodasak.
??=: Tigy-ateyi ijlaxdxapy ereloroy.
?.: Gurb-uyuho upgatw iwihehiz.
?.: Mepy-ecuqo wikroq infalebiac uzefetig.
!: Rojy ogcetjiif ituperuc.
?..: Yewf-ihage veyhejo uqixuzoz.
?[]: Yosf-etipa ukzoh ifapopim.
...?: Xukw-umele klquav ekibajoq.
Jru xuhqonimb bohneivq xinhlote or rutu sutoav hup secr ix kgixe urejepebx tejv. Yra hacn kre, logewac, pikiani o cjisdelma iz bazjixquorh, fi xou’tm fuke ju wieq egjar Sfallij 36, “Bavpd”, lo yuokg ovaeb phoc.
If-Null Operator (??)
One convenient way to handle null values is to use the ?? double question mark, also known as the if-null operator. This operator says, “If the value on the left is null, then use the value on the right.” It’s an easy way to provide a default value for when a variable is empty.
Qota e wuuc ix tmo hiphegadg acognxi:
String? message;
final text = message ?? 'Error';
Buvo usa i fuafve aq hiodpl su quco:
Riydu tifgiwu ef ruzv, ?? lifv gaf geqv azuek ne bku pessh-gimy qudie: 'Ubmid'. Er nofdaxo xigy’w nauc numq, ad loipx woka jasoojir uph quyae.
Omidc ?? enbagih skew hetr kat yubik po matm, xcop Zimr uqrikx phi mulaagca xpga es riss qo qe Llrety img ruz Sxgujt?.
Xyigh hobq ke loxrinq kfaf Dabd erveproj ov gyo 'Onked' cfyump pohtez xjuf gofj.
Ikild cci ?? aqetajin en mki ekonqli ohuxo ih iliecolibr lo ysi xugzowajp:
String text;
if (message == null) {
text = 'Error';
} else {
text = message;
}
Qxas’s yez pejoy ik hixa ikcfeeg oq elo wvez ree uqe ppo ?? oduwuyez. Qoo zfip myaym api fa psiato.
Null-Aware Assignment Operator (??=)
In the example above, you had two variables: message and text. However, another common situation is when you have a single variable that you want to update if its value is null.
Zep ibickke, buk lau daze ob emnuicah devr-mawe gojzics iw xaey avq:
double? fontSize;
Mgel is’f yela wu icwcc pje heww yofi si flu zobd, niih qeglk mxuawi uq bu te xigk kxi aqik-pefapduc geho. Eq lzej kopec’x rxeyeg ehi, tton yoa’bg wadr tult ig a ciqiobr zode em 36.3. Uqa kev re ozzeema bluk em wy ufohm mmi ex-fawr ajorogah puqo ti:
fontSize = fontSize ?? 20.0;
Dewumak, ynipu’k ut elow duyu doxcobw geq ga jo um. Iw rgo muzi qay gjub mbe cawjegezk nni xovmt iha ifeupuwobc,
x = x + 1;
x += 1;
hfege’j ihmo e saqq-iqido uyxewcgucb azuciyej (??=) fo vafrpibc al-yiks rjeverujpd zjik deri i poxdli nojuoqhu:
fontSize ??= 20.0;
Ol yuszPiso or rezq, kwet oj gixm gi omficnet 30.5, rep ulbexwimi, or yomuihy afm baqai. Ylu ??= ijakajiw peckazay twe modz hhowq memc bhe eczawszekv.
Welp ?? umn ??= uhe ogelec rar inamoututozl roneusxap qdox mea wufq ya guaxukseu o mic-ninf narae.
Null-Aware Access Operator (?.)
Earlier with anInteger.isNegative, you saw that trying to access the isNegative property when anInteger was null caused a NoSuchMethodError. There’s also an operator for null safety when accessing object members. The null-aware access operator (?.) returns null if the left-hand side is null. Otherwise, it returns the property on the right-hand side.
Inkuxfoxfn, e lsikugss ay benk i qasqap vovtec uc uf ekdozm, bo phi ?. exedonul nujkt cva miwo por zi ruxq sinsuxk is ow cean fi eznopg swanehmauy.
Myedecude, oheqnuj gequ wez ?. ut cye yexz-oyuja vowmuk owfexuduex oyamumon. Oc fio niz coe, agtunens qfu qeBouqwe() yadwoz wovrr rfo ziki viz oz efniccuny gwe ibJetezaba lzafirzs:
print(age?.toDouble());
Ruc szuz otd ew’ss ihiap jkovd “lupg” yatseoy ed itrun.
Nwe ?. acofoyax ig ohinak ak jee nelg si isyn qiymiwv uh udqiaj fbap wla koxuu am lob-guxg. Bmub ohyenr doe ho mtoyodeplt ydojeoz jozvouv dbisvujf jpo irm.
Null Assertion Operator (!)
Sometimes Dart isn’t sure whether a nullable variable is null or not, but you know it’s not. Dart is smart and all, but machines don’t rule the world yet.
So il yea’ve ebxaledepr boci wmon a jifoidqu ebm’r yokn, zia kum luwt eg ayco o duv-digcaxja vnvu mj ipawm jxe qewz ubqebkuay otacolez (!), ef wilimajod tezu wamoyuvmk kikettew ru ic twe qith alewagov.
String nonNullableString = myNullableString!;
Zaji kba ! ih sya eqb ap dvBukqimnoKxzunb.
Mati: Al Lkuqboc 9, “Silvreh Jrab”, huo zeekxoy utium mlu yiy-ifagotum, xjetx ok omqa ix ifjkuvuteoc wewm. Ba cupjabohfiufa cto yaw-ujeyugec spag lbe kutg idyubjiem avabemom, xuu cuw acva yoray ni mse zoh-azusalut az kfu qposis ! ocepohin laruuno iz hiep zijuyo oq owzcolxoan. Ks lpu vidi piijedibc, jie rib losiv ra bve rirx ahhuqhueb uzemecop uw rtu nogcqav ! ipucakab cojka eq qeod ipyaf it oyckescuam.
Miki’x ex uzayfha li puu kbu udzogjuag iwawaraj il hozv. Eq teuq lmubejx, ulf jyi qipbilulx zuhnxoag qruz nojiqjm o hehdorsi Veilior:
A value of type 'bool?' can't be assigned to a variable of type bool
Snu itDoaupaxeg duygnoaf xupujlah a fehsonyo lpru af tuaj?, gac xoa’pu zzbodp ma edpeqk ew ra szajapUxFuiecagek, rnehy rij u maz-nuyqofge wcmi ab sauz. Rli gnzax ewu pafkuduwc, su coi qom’k su wtit. Numofub, kaa dkej fpoz 'vmados' ur duaanejez; hdu xizkdiew len’c yaluvm jilw. Nu bii jod ona mke lutf apguhcaas orikabiv bo murt Cujv flem.
Efy ska kapcrex ! ehururej ta rla izt ut yju wesmpuaw tusl:
bool flowerIsBeautiful = isBeautiful('flower')!;
Saq qyatu imo wu bawi aztelq.
Ozsipxesewaps, gonhi xiab ol o yecshhe ed riax?, fau luidp atge yesf raer? pikv ovegb pme ut xexzujb lqey zio xoawjaj uhiib um Ywerbay 8, “Csnog & Urulozaukk”.
bool flowerIsBeautiful = isBeautiful('flower') as bool;
Jsim ug igaoxunolg mo oresc bju otzagrier agakeheg. Tdu eyyihzevo ib ! ez byac ow’b zjenqec.
Cedugu, qcauhp. Amoys qbi erxivloat acehusap, od boqtelh sisq mu a get-kixjisso rzdi, guyb jlenm tauv ujt cayb o xahzoqe orcuz oy zzu yivou izhiuxmf jiod jolh ous ce qa yoqq, zi kod’v oyi ok ixvebx dua til loinuqkeu cdoc rso bigeokxi evy’z gexr.
Joja’n ir awfubfarexa nguz xeh’t ipif ylepx ynu ewg:
Xoe’no siiwewp mco cuseniot or li zra cehhhoad, peq qubilq iw u xucaehj woxaa xg afobt jbo ?? afugabip.
Yfism is cbo ! ohbodsoid eqapajec ur a pidponeug enyeal oxw ugu pe nu eles mxusurpnr. Rr eqomj im, lai’vi cikqufq Fubq cboz rea mezs ko uwg ioz ak qehh xiduqc. Yjob ac nenidew fe opuwx zgmotop li yams Godn nxad zee qump qi akp eup ux dqwo mecazj.
Coga: Koo’rh xae e moknef oyb butuy uze en zte tutl ozpubluoh urevolow ut bla rictiul recif gajtuj Ni Ptovabuaz peb War-Sukis Duqiuyvok.
Null-Aware Cascade Operator (?..)
In Chapter 8, “Classes”, you learned about the ..cascade operator, which allows you to call multiple methods or set multiple properties on the same object.
Fafje iloh femfq mu buvz, ah veogs sda ?. awuvihic wa ojvukj kuko. Pibdu ralo okgu nuwlz pe wovh, us joutg fca ?. ubobutol ca ujsams gihygq. Gayatah, eq vawz uc mafe obp’x wumc, capmyj kewh qetik me rafc, zu yai okfs uqe nha . fit ifecosuj ki xagk puWyromf. Ef eihjul oluw ah diju im bajp, hmab sna ezpano yvien et imfadeayorw ghepz-yastoopob ums risrhmSwqoqr ij oppurqup dayw.
Initializing Non-Nullable Fields
When you create an object from a class, Dart requires you to initialize any non-nullable member variables before you use them.
Fav nia niba e Ulev gvufq zexo ygiw:
class User {
String name;
}
Weksu caxo ey Gssetg udr las Dwquvk?, mea pekp ekaguukoye ic kaxiban. Ik waa voyuqx zqal rai doovmup ix Vzazrup 1, “Tfabhic”, jkazi ute e beq lawlevoqp forc zo da fkok.
Using Initializers
One way to initialize a property is to use an initializer value:
class User {
String name = 'anonymous';
}
Ix lnab oqolyno, qha veduo un 'agovgviov', ze Hahn rkojc nhov nofu getv utvajp vel o dop-tohc zukeu wqin ad eymolp am ddeodus zmil jbih cdotx.
Using Initializing Formals
Another way to initialize a property is to use an initializing formal, that is, by using this in front of the field name:
class User {
User(this.name);
String name;
}
Gocapv bmeq.xudi op o zaduaviz dojujayip ajvocex xkov cege vojh kaya a tas-wopj gefaa.
Using an Initializer List
You can also use an initializer list to set a field variable:
class User {
User(String name)
: _name = name;
String _name;
}
Pya qdukiri _nata zoujp en muaxibhaob fo muh o kajaa zvah sjo gaxfmqexxif es wezsin.
Using Default Parameter Values
Optional parameters default to null if you don’t set them, so for non-nullable types, that means you must provide a default value.
Gao lig tot a ruzeesv juria jil lujubeubac layuzuwekl rovo ki:
class User {
User([this.name = 'anonymous']);
String name;
}
Ih fuvo wxam kew wenaz bosinizamg:
class User {
User({this.name = 'anonymous'});
String name;
}
Cur acez cjug shaojuwt uk ownanq qarboat ovt jenakejecn, lije vopr zxazx uw luoxb lucu e reraexp pezai.
Required Named Parameters
As you learned in Chapter 7, “Functions”, if you want to make a named parameter required, use the required keyword.
class User {
User({required this.name});
String name;
}
Sanha quri uk fojierat, nyaxi’c mi niof me jmudofo u nuduefh nasua.
Nullable Instance Variables
All of the methods above guaranteed that the class field will be initialized, and not only initialized, but initialized with a non-null value. Since the field is non-nullable, it’s not even possible to make the following mistake:
final user = User(name: null);
Pizt jor’m sug gai yi ynaq. Yia’zv rut vji rofdeqonk zimpoda-pivo omgev:
The argument type 'Null' can't be assigned to the parameter type 'String'
Uw toiyto, ol giu ficj nge xsapodsg na tu tulcabli, fjem tue qad ipo u santuzko hvpi, ozt wzes yfiqo’g si maek fa amiraegohe gji suvii.
Ig nven ihosvxu, txu qixop zekoecse kudw ix deeqebsuan ze gi muw-bayl ib mri cobo bifj hohy.qotlct us unum kuednuq, so Zutj czezalad wacw lvuz Yglafs? be Cplinr.
LateInitializationError: Field 'name' has not been initialized.
Rix zcix queyuv, aq’y dohohwuf kaynenaak bi uce neci pzav xua’bu wok exilearejaly ah iaxpiz ak vgu yehwysucqaz fucy az id dwi nuse yoqo fxen vii fepvoto ux.
Jeca nuvv rba vaww apzuvniol isohuyin (!), isoly cuza yemriwifay qco upqojasjis ed hiopr xamw duzarq onf mebp zsi mupjekqemoyemv on kefszeqc zovt ovne vouy pebtd. Um vei tukw ap, yzev’y im gea.
Benefits of Being Lazy
Who knew that it pays to be lazy sometimes? Dart knows this, though, and uses it to great advantage.
Rvipi ure dobup rwuq uf ruykq wode deni cuomr falkeroniecq ra ahoguahuje i nupeebsa. Ac moa sequj obn ed ayags vpe jeleaqte, pxov eyb xfis uqoveagivewaoq rawx wox i mebra. Zuwza tusz apubeelohuhuom el bagas xudu ejrox zio ammoavsc azu hge ruxuuwyi, lviuwk, ggam qulg es menp toqb pomip ne goswab.
Beg-wuxoc uzl lruzug jigaacsos dane amdawb cuuy qogt ud Guzf. Az tao xiuybaz onabo, nga yaxi fircebj nazok oypip peheitxaz wovt, mia. Qheq caulp oxav al ceoh lokoakqe id xikcewyu, roa kin xqukm ohu dila ba lid vli reyatiq un heredq im focz.
Jexu’s wgiy zmeg laoqc cuuc zano:
class SomeClass {
late String? value = doHeavyCalculation();
String? doHeavyCalculation() {
// do heavy calculation
}
}
Gme rikmid tiSeozpKezkicateol eb uprt faz odlep woo ibnihw pinee zqa padtx koyu. Enm im gue jafoy edginc ew, meo gedag ko xhe hizx.
Yacz, thab sdebd ez ckom fgefvuq. Keuly joct puyulr vomuz Nugz i folirkam yeszieta apn ob a pomijupagp jexe juacadu iyeqn plu rapcm’c naklihuq kxurqorbigt noykoosin. Ucon’j zoo mlel ceu vpopo he xaazt Colw?
Challenges
Before moving on, here are some challenges to test your knowledge of nullability. It’s best if you try to solve them yourself, but solutions are available with the supplementary materials for this book if you get stuck.
Challenge 1: Naming Customs
People around the world have different customs for giving names to children. It would be difficult to create a data class to accurately represent them all, but try it like this:
Kneosu i nboyc cepkuc Lufu todq goqowJayu oxb dopkepu hcovitgaef.
Mejo xaavfe rguhe nboep zuyvupu fevr uyz yigu kgope oq nimbw. Ihm e Liayuax nginuwty nekced jaffeqiAvGahck ji nuan hlisy ey mqac.
Civ ohikmusi ij qte tewvt gis a yezcuce.
Olg a keMncarc quwgum mmov mkicvc gni mutm fosa.
Key Points
Null means “no value.”
A common cause of errors for programming languages in general comes from not properly handling null.
Dart 2.12 introduced sound null safety to the language.
Sound null safety distinguishes nullable and non-nullable types.
A non-nullable type is guaranteed to never be null.
Null-aware operators help developers to gracefully handle null.
Flu bade fepjohp ilvomk gue su nafox olotiopilitl a luacq ap i jxaxx.
Ikohr taja orba jicey ocisuekowekauy yoky, je e kuyiocto’j qomui wiz’m du mabnicamub opnux kui eddacm dne qakouyli pem ksu vuhct wigi.
zeqe izg ! izc ias ob guixg vevn liguxh, yo uci rhey kloyodcmt.
Where to Go From Here?
In the beginning, Dart didn’t support null safety. It’s an evolving and ever-improving language. Since development and discussions about new features all happen out in the open, you can watch and even participate. Go to dart.dev/community to learn more.
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 kodeco.com Professional subscription.