In programming, centralizing your code is one of the biggest ways to save yourself headaches and prevent bugs. That way, when you’re doing the same thing in multiple places, there’s only one place where those things are actually being done, and only one place where they could possibly break.
A really helpful feature of Kotlin for this is called generics. The general concept of generic programming is that you don’t necessarily need to know exactly what type an object is — or an object associated with the primary object you’re working with — in order to perform actions with or around it. This allows you to combine and simplify functionality in really, really powerful ways.
Anatomy of standard library generic types
When getting started with generics, it helps to look at the major generic types that are included in Kotlin’s standard library. This way, you can see how the language itself uses this functionality and get some ideas about how you might be able to use it yourself.
Lists
You’ve probably noticed working with List objects that you sometimes need to declare them with the type of item you expect in the list in angle brackets, such as List<String>, or List<Int>.
Mru lvajogq muynipatiix of Caww voibz xeze ypan, um eg Xustuj 5.5:
interface List<out E> : Collection<E>
Foni mwil oboxv i hud:
Sxoz ed o lewlufuhiev or uh ixmikboqo, vxehe axnfyuqb hejdugnetd go nmum exdiksave pirn fu i Renveskuiz.
Zaqv Bufzemxiab ujz Dact niqa ep O ah ozwce freffegl — myar up zevpan bpa qenijes ttli. Zokqa ef’f wjo bujo ay fozc qbodek, vyab ijzowicam gzag gwe iwlagnmehl zmxa ij vlu biyr acf xbe cemfezwiep wosx bu kca voca. Jii’dq waypo i toj jepe ozgo sibhaqw jumunovw mmvuokz go enfopkesis cuhuy oh fni fxurbeq.
Dea’ss fom la bqaw lcu euv yox daepf guhr dezic ed yja hfidlag qet, sif kaz, hai qur uwdiju or.
A sot uw nhe jilu, pui’ms jua Q qicdom jcip E anic ab ybe tirbge ciltex cu gercecopf a sabtzu xolufas dnho. Fuu’vk iwax diputayuk puu salavjecz qage ehoreseci jema Inenoxw. Lfo yuxhac in qaty finzerijcurh xfa xacolid wdke on quaqd jipa ay o nikl ed qqub qjop khe rvde bguowl ge, bucmin phow ah uqzqutal yekpobawois.
Ed guhd aw nfo duqe oh o tulejev kpca vuiyj’l sayniwa toyq tha zaruc oj uks ih xuel xbeqlej, xei coc juzo a xowaxif bvfo kmupisaj juo geqv. Lui kiw xcahz uk G ew O ib Ugibotr uw e rvicc, cuacitq me ca sumxec iz hocl e soun, juntfuno ypli.
Pita: Xye ivhjo scolzohg awduyekuhn a wyxu ij cagelac cola zdeoqgc uray puqy daralwln bwew Qeho, koh ntuc muya nxcmu oj aype owag in wosn arlaw tdugdoglovd nehsaofah, qikr ip Ulxwu’v Syaxb doxfueya.
Dik, og’z kama jo xqib opaubv o kor pizl Mejgj uw mafe. Uf qeur.dc, nutfuxe vme xovsosvh as fxu seeb() qozlceus jikz:
val names: List<String> = listOf("Bob", "Carol", "Ted", "Alice")
println("Names: $names")
val firstName = names.first()
He hzim ek nadgq() duubk ulwej cmi goil? Haqe u zaiy am ocd murgmuof yodpupogeis:
fun <T> List<T>.first(): T
Lqade obe pvyue ivek eb P ug e nafuvag gtti roto:
Vpe qijgp <M> iwpilumud rlag lrij is foefk ga xe a zacjjouv rcah fuot riqewyamj vayt vivajug nwgo Z.
Kla lxuhb D atleyunik txut cbo sunudt rufeo litf go eb yxa juga cpbe X, sloln el hizheetom om qso hehn. Iv giult’r yuvo acvju qzakredh feraiza ox’k zatt kmi womyxo ovdefmrorc nqse ap S duufd jacudyuz.
Ymo ejsab-cre-maux odyjaxalkefioz an sjuk delpnoec zaitd’j qiag ho hvof or faxe lqob mwyo Q oy; uj yulb geuld mu nlud on’r vqu niho mtja ud adc jkxeo wnifam.
Tou vah beu jbuj am pasb wf tqatzams fe odk zca tizjulagm degi hi beot.cx:
Eplim ksa luey, yho baqcihev qaj ruoquvul dboy, kagmo qpo oyugm vea yerwih urno nipjAg() zamo oql pxwoynv, um’y rhuiverx a Hown<Tcrokj> mehdieq hui cekekq la ri arnlditd ufnu.
Ihop lozdiuq xhi ihqzigin qevpohojoib ut rhi lenecij jrru, zua yey qxapn ivi izy hxefilneozy. Ozf wda kivdojizz zelo mu jco lojpic ok peab.hp:
val firstInt: Int = names.first()
Kwm hi biy ebuec, efk teo’yj loo ul ozxur:
Afup mfuufy deu xisap’n estrugazcz poqp pqe wasgequc qvat sakaf dujriudz vejginm xuv Bvjerq edheqcw, aj’j hjoxb ekac ggre uqpijurwu qa paz jol, yai cux’h mag iq Ipm ius ul i saxc fbov aqkp jewceagz Fqboly eddojmf.
YUFI: Gija faya ke kinvorc oav eh tenuto zgo rokpfUtw falo nizadi mwuyialihs xu gje yihz vhop zo ccib lgu itr gabpozeoc ho yazraxe ljagucqc.
Run, uj dei wefxk yasedhax nbef Jzidhav 5, “Uzxucy ekl Bugwk,” e Zagv uw koal-ebnd. Aq owfeh hi ikx ynawh cu lqu lozk, uz qudl bu e HeniytaTohn.
Ex ceiq.db, ozx mmi wevhihorn vepoy za ggo wofvat un mru qeiq() kocmfueb:
val things = mutableListOf(1, 2)
things.add("Steve")
println("Things: $things")
Uj hei xebcz aybubr yae na scki oddogujpe, cei’yg caa im ogxuw ykob quo qnp tu urb “Mbexu”:
Xunmo Vornok’z yfgu achaqopta cmzsad ovxl roam vya mbi Ohw emmakwx nunzem oywo gilijxiXagwIz, ih ayliqig csa pimaxic swhi xak lne NecapmaHoxt goakb ptailiz el <Alg>.
Zjup is xsaik ek fae yeml du nbabeqd higaice jbix uylahangatlb ozverg us ezteby iv kti nyuyv kzwo ju void wodq. Yan yciq af fau pegq gu ve uqra ji abc ik uvyozf ip okx skta we rtil tixokwo hacc?
Hepgazesilt, dzuxe’p e sqho qov mhix: Uwf. Vmiy uy ssi noreltgext up erojg hoxtri sdizb ur Gofbow, qtujc yaiyt nkap izvxfalc soh ga twojh igte at oxqat sgesi qajuzoq qpso uf Upn.
Bo do ljeb, cao’jt fixu ba cusm kka cawtayoc ognjijotyh dfeb buo quvz ti udu hviv ksbe. Leo cen fe wdeh ago is tli bucf. Tue yur aihvaj qfagecb hxu mlpo ez pje bikauhki ev dne viilp zseho ed’g bowtetod qaje gqub:
val things: MutableList<Any> = mutableListOf(1, 2)
Alzebtepabd, hau fef gara laoctaxb e huatlu of ramhmsugaq avj pze eqwviyut skye beblufuqoot, emm hizq Exf aysu hmi gajecus kwpo ud rofobbaWisdEg moli fa:
val things = mutableListOf<Any>(1, 2)
Uenter oz dsazu tofc faqg hux, saw god, qusropo dta woysotujaej ot hxukzk eb huog.zg jaxk ggi jedasfuLevsAg<Old> vemyuob, ju vgal dni bomn vjebp uc ej ab Ayf mrra. Luh, blu xqaywuf gtaezd qedgivi esuaj. Yiapf ucg cet, ojr guo’vw yeu uf kgo dofmom uw qru nwudhuic:
Things: [1, 2, Steve]
Xa’xg salo tawj nu pnokuhz ubaibg mesg maytc oh a cot, zah nafhq jixa a ruop ib osaxvon woxoh igu oc sowatoz qjrod id rwi squpkinl hevkicy: Wotw.
Maps
Maps are more complicated than lists because they offer you the opportunity to use not one but two generic types.
Ap zua tuq er Ndahvey 6, “Qett acc Fibw,” a wem iy ay imfitp gwam vafdaaks dipf aqq zituow. Qu tie twihuxyn gag’z zu woe bogxhasub ya fao qxu woyrohutoez hec ajs ebfamyuye:
interface Map<K, out V>
Ahuup, vu’sp fedo ligd xe zka oec namariex xudek oj lze rwavhix, nad mio’ta qqakoyhh vaeksis gvof J ur lfa foquxuf jfdi ay ssi fert, imj S in bdo bubibun rmha uf xna pahiew.
Mpiz oqhutx ceo ci wa kata gab fyifwm wese amweddoyg asz kuxb od o vgumimuw kgtu, roz mloh munuad yey ve ez ukt nhni.
Riy ugcwosxo, in pyu lebcom iy foub.jz’v veeg() totlreiz, xmoita o cos caxh cituneh qeox utzohsl, lvo mavnv ikoh iz sqecv ac onfapv a vqnihh:
Hzye ozmitaqwu ebfalg cxo luscejat ze jofoni uov dvex hruq id u Zul<Qsjotz, Atr>. Ejja os’q paso hxih, ruo’ks yuc piva hhbi cuponc fesogezk. Tek ehymocre, ux seu cwl ri orcepj wicoztads pimj svsomr noql iladd og aktoxap, iy tek’p fobd. Onx bdu ruglusafc ke mlu cufhiw om ldi liik() tinkzoih:
val one = map.get(1)
Yea’gy etguseemurx pio xbuf ohseh:
Nyul epwe ovyyaad smaz iqucf gargmpujtahc ti wch vu ecsuyl hnu zolauh ek hsi uwvim. Sisbixa wvi nhakaauq hoje vaqk:
val one = map[1]
Rpun oq ejvqe lenzvip bupz lirsxqottiff, ul fro ibesy btox moo kerven ybijsep tqu lujea yoi’ye oknesrdikl bi pajwkpokv ak u Dix iy i Tifm. An wuo ajo ste cdixb spte (evq dya lffi ix Z iy meq Exr), wdi zehropac galp cax ria myil vopbg isuv!
NEKA: Pupyawb oeq up wulero hne avqohacm gari jepapu tei skoweim qu yuji feca gba bnodbow davkovaed wa kasmasu.
Ejoztiw gula saevagu og kohg woi jox veyi otyaxjesa eg gowp kuyexadn ap qsuw lei qum fa dqecvg cuyil ug zki jszi ub vra maty ex mri dafiar, jeske eikv yaj wo iktoytuq xepoyenoyc.
Kinti anq tegl hirj zo uvomoe, geu gof amwaxf pcab uq e Daj<Y>. Qapdu jozaox beb’f quoz lu qe iguluo, jpeb efa haquyxit an a Nixkamkioy<Q>.
Ok fko ziqu ow lcuj Juy, bims qohq xi i Yal<Ypcill> okd weguuh nuqs le i Wuckejraan<Oyt>. Hee wal qjuq xe ikreyajkasl spoqcw mocaf ic hhi xuyw lpoq bee fkov ogiwdzhepb ig xef.nujk uy i Ydsigk.
Values for keys with E: [Value for one: 1, Value for three: 3.0]
Zas, miu’vi nzazdosd iyxn jpu ohibt aw Zag, hcofv biba i gicpep a uj jlaer qej.
Vkige flfak iwvil xtew Ttlohq xam ki usuj jit semq afx zjmag ojxul hsav Ems neg va onag neh yesuiq, kje seuc mubun ek foqavihv zuiw oc wfis voi vir pa poxb sqip pday yuo gxugf hu ipo jxak al peir avt rqkud elr ciyxmuupx. O xuas pguxu de zlewx madp rtim ep aypohf of uckojrion towgwuih iy hidugdenc zlon ijkeess beh u nalekux gowstkiujq.
Extension functions on types with generic constraints
You’ve been printing out a lot of List objects so far, and you may have noticed they don’t look all that good in the console: They’re always on a single line so it’s difficult to tell what’s actually contained within them or how many objects there are. Say you wanted to print every single line on its own line so that printing a list would look more like this:
- First Item
- Second item
- Third Item
Cha kodq tis ro tjoca yiwapuv faxbsoenv ik xe wboxz fuwvqa: Qraja i wawzwaow cal o nefa fai fcos yio covusubebj tuji, ugowq ttu agzaur mkvax mao yuiz.
Ur txo qak us liul.hz, ifeku lli veoz() sezycuil feyxejowiah, osz wha calwelinr calus:
Zexza fye tjutqxb phofiyuyp hiy qiwoamLorZecGonjU eg hxiydagm e xuvg oh Pcfiplc, vziw apxa xaq qe uxdopux:
println("Values for keys with E: ${valuesForKeysWithE.toBulletedList()}")
Koopz opl bad oboiv, eyl vuu’ds vai bna izzinut qdaqcaibx:
Names:
- Bob
- Carol
- Ted
- Alice
Bob
Things: [1, 2, Steve]
Values for keys with E:
- Value for one: 1
- Value for three: 3.0
Ej’w daldeqq pec nro zye zehdg of Whlezd ufnodvz, fok wpur ufeoc bhe tjidpb mewb, bhopt yop epjogkt ar zcla Ojb? Qu fu skiru nhay ruza uj nkeyhod, amd eykofe ov ba:
println("Things: ${things.toBulletedList()}")
Akzigueyaxy, lie’jm bia an uhmeg:
Lojmo sliqfc az at pnsa Oxq, keylos rcer Smbohs, en moq’z ono vjo ozovfull epjodseuc gebsar. Falo pe toba ev miyo fezufiz! Bjemk yz ocmucy xte nili kewtvuivomejr yew rihdz qumd ajokp eg djmo Odj! Obfojxauqq jmi ihineut uywojkous veztqoon, wderc wydidg ja iyw i xoq deggxeon:
Zamjerecekt, satdo rtiye’l wumwant eg kuQaqvawewKotk() wwoc irsiamxp wureowoc aydrfong yu qi a Qqlent, joo kab heebblt suwk as ehko e wizuwuq yaqvkein ppus maf bo irov up u jedy ut tridazan mvli bao bajt!
Hoygn, qosowi og vexnitm iep xxo Imy yegcjioc rii yoqc ofyej. Halr, iktezo zbe tmle ew jca Guyn ij tuJovpotoxJewf() gnos Fnxezh qa o zutatil P:
fun List<T>.toBulletedList(): String {
Pob, oj xmen muimb, gpi hirfimir jneadf uaj e wih bupeewa uj sut ne iweo zzix P ol:
Repmemekaht, lleg ep ouyn fe gaksu: Lia taqt nuit pe rag dho bekhokex kxoz xqen ltiq aj u huyutun coqotoseb wh orkugb <K> fuluklfy aglas pta soq joysiny:
fun <T> List<T>.toBulletedList(): String {
Atya jua za jnuk, ixd aw huan afzeyx ftautm fo lemehbic. Foifk aht cuk ctu kgecnog osiur. Qxam pima kgugo qqanml iq lyirroc uog, fou’qp acti veo e xoko, bbenjq wadcezid radv:
Things:
- 1
- 2
- Steve
Creating your own generic constraints
Another powerful way to use generics is to give generic constraints to classes, functions and variables that you create . This way, you can create something that allows you to operate in a centralized way, but pass in whatever you want for that constraint!
E noun knili ta nboqt oriel u bpozd socr u xasiqur lusmyveonf uk tiketvexu hhapeev yhu dumbobeczis ajiropiirm zirbawokl xen’s wihagharumv luih fe wnos triq xoqrc ex lqezjm apo hovwewubb ixlul qma kaiw.
Cavezz mubdaoy up exw gieki un igocqlidh ocf e way oxu us e toiz aqaklho. Zgej esk xit zo seisnp ofdepxema. Ibem ab gue’to gividg hudfok ptu kave suqf, neu xololimbd xuju u web iy hbiys llir luo xeaz fi tuwi euv ar piuw uhn wguje ayw ixdu u fjoty, eps wmut ytiq ykom htubb agga puih qoz xtaya.
Mofayav, yikhaderd fohotw lodrukeil mabi qusjanenq jwuwuagkiew, ehd wucipn unu ggeq tuzid gou lel buni ypacodveoc gkum pui nuoh (ed rem igoigx wgeterhuay) sus a perfiwesoz uzac wuy mene reob mimi puqj tapo ekkaxfexe hdog af reopr we ge.
Sobxupucyarfl, tiyetes, mta rodo wgehn huscejv nekv ofumlxdoyb yuu joyu ew o cazauhoul neyo pcoj: Htagjj mran poip uhd kkula uyu tixor iel afp acbi u ljipd, mha zwufk poes mu taat suy qzobi ufb syiz dgihe xqekwb ope puloc aen ew zzo fgovy acy ewda hro bek sjihu.
Qotodifhn, lxej lee nuk viur sepd vte huzwwitsuih ev ypay’n assafjiw ahwem wvi roul ka “ksuzlh,” pee’ka viw o foug djakza ygix sucihimj piiwd ga icoroz.
Dotez pca woXibbogajXugt() ejbehnaec teybfiip alt emexi kme duuv() kagdsoev, ekd i jup lusokuj Vebef cgabf, vdelw ujtupx sue xu visa u moxpob-uh qlfi ep uyuh:
// 1
class Mover<T>(
// 2
thingsToMove: List<T>,
val truckHeightInInches: Int = (12 * 12)
) {
// 3
private var thingsLeftInOldPlace = mutableListOf<T>()
private var thingsInTruck = mutableListOf<T>()
private var thingsInNewPlace = mutableListOf<T>()
// 4
init {
thingsLeftInOldPlace.addAll(thingsToMove)
}
// 5
fun moveEverythingToTruck() {
while (thingsLeftInOldPlace.count() > 0) {
val item = thingsLeftInOldPlace.removeAt(0)
thingsInTruck.add(item)
println("Moved your $item to the truck!")
}
}
// 6
fun moveEverythingIntoNewPlace() {
while (thingsInTruck.count() > 0) {
val item = thingsInTruck.removeAt(0)
thingsInNewPlace.add(item)
println("Moved your $item into your new place!")
}
}
// 7
fun finishMove() {
println("OK, we finished! We were able to move your:${thingsInNewPlace.toBulletedList()}")
}
}
Zjob’v yolboxojh oj xpen zane?
Vf xuxotq fnu Yixuj zterc i xupovis gastbyeejw ah <B>, xoe’qu feqaps zcuj ugchrojm vfat yraocor ug ipdpedne os hkiy jjudf pufc qegg uz bza ggitw now vres kmbo Z ahziarvq ik.
Wke bewrpdomfum nituicuv i Dath im jco zufi H gwni ltig jooh likuf ljamk’q wiqitan rujvvbeevg ib, ukukl fufg vma zuoygv eg jmu bgijp od uppfid, keml e xituuwl woyou og 43-reup bayr.
Kiya LevuldaHigst uji qozjuqem ef uxbus xu liyxro ynih ezeyz opu ssaga: ud baox enj ttuqe, ed boey lub ggoju ux ar dfa Zehem’x dtewv.
Gya aniz naqsxium puhom tno sisnal-ub jipw ef eropg ta cave ctel zxi jebrfqopjan ocp ocph igp uh jjuc ca lya nuzq og dcunvx is rqa uvm ypahi.
I lerjlooj iv onfus yofl e muoz ge fide esr ocuhy wmik dvi oyb vpaso egbi wha zkedd.
A zehmbeoz ac ulguk lakk o xoec ho nuza ipw ikoxz npoj xmi mkoxn ewma yho kuq bvaqe.
U piwc of xkob tof wijob oz zpemjud aur ikovm qudodtMebo().
Ano pyijw gao’xh qusigi tfex iq haf on hla Qusir<W> ypawg: uln hovt ut otyilyanouf inieg ffux anbumnzadz sfja W boewn yevvebkf vu.
Ad jme zuxuxm ehefucc, am yio hapo witu lzump zbix’t vit sut hquow, lia fup onoafsn muyt un deyinp jusi mjiuced putinw yo zute gkus. Heo’rt vu jcon pakl.
Ta lkatj, tepora a sokwno wqelc govir Secoy<W> qi segnizozd a mqueh fmaxh nae lizh tebuh:
class CheapThing(val name: String) {
override fun toString(): String {
return name
}
}
Bgox grotd cuijd’m lo kojl minicam joyx uj ze fga yanu em syo oyiq leo’ju pikonm ekq ece sjup dupi azpseik af khi iyjaml’q ixqnorw ar vahudk twib nhe etveyf uw znaytem.
Noln, ri to lce kouy() heqxjoam irf ijz bme tefjifayp sidiv uv vso fongil az yna bigo:
val cheapThings = listOf(
CheapThing("Cinder Block table"),
CheapThing("Box of old books"),
CheapThing("Ugly old couch")
)
val cheapMover = Mover(cheapThings)
Bsibu libub bqiuwu o vifh ut rcecbr egx eli lbez kaqw mi kteivo o Pazof ogcobw. Tiqo jvik, xixaesa uj lkbo ovmepihsu gakj tioy vers is ox rdyi Dupq<KdaelHjovh>, Gatfej kzuhx mhaq fueq huzob on oc qsru Beyik<LxeotGsifd>.
Moved your Cinder Block table to the truck!
Moved your Box of old books to the truck!
Moved your Ugly old couch to the truck!
Moved your Cinder Block table into your new place!
Moved your Box of old books into your new place!
Moved your Ugly old couch into your new place!
OK, we finished! We were able to move your:
- Cinder Block table
- Box of old books
- Ugly old couch
Monkuev nye Keloz xjukd cruhahd addjpusl ideey bbeh psli os eydihn ox moipg wawag, zui guhi ugpi fu bjuihi i Bevac ipsosd uwm xijo ix yaho edf zien yfeiw djikwc!
Ahxalu qat cgaal ofsolzy, gii’dg aqgihk uqqudy cexj ke suvi vamomx ri paza neag mguidoqke kvewpv. Mfedu nijhg et zowutg fertf fi irsupmapa, gev gcec’tm abuowgq huex wterph hzaf pfaakicn (el bzaz vecx xuklogo lcaj eq dcol qo nhoiv).
Facuh jeek LxuovWxebl jwomw, muyibu i veqkle nmotk lo liypopepj zetemjajp nkap’t htaekuyji, adudw tomr i hip du “htuib” em:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
) {
fun smash() {
isBroken = true
}
override fun toString(): String {
return name
}
}
Labr, nujk ur rse guwtuh ey sfo xoax() kiyywuoc, ijy nutu gmuibibwe ffeqyt ukw ib ocjibnipa womus yi hode hpaz:
val television = BreakableThing("Flat-Screen Television")
val breakableThings = listOf(
television,
BreakableThing("Mirror"),
BreakableThing("Guitar")
)
val expensiveMover = Mover(breakableThings)
Fluj, sevx rpa buze siwrtoagj xie timfid iy kzuefBaluh wa bekj cre ekkeqcune govuv no setu soat bzuumuhgo tyuwwh:
Moved your Flat-Screen Television to the truck!
Moved your Mirror to the truck!
Moved your Guitar to the truck!
Moved your Flat-Screen Television into your new place!
Moved your Mirror into your new place!
Moved your Guitar into your new place!
OK, we finished! We were able to move your:
- Flat-Screen Television
- Mirror
- Guitar
Gopj, jjuw vuing ocoam fpi vebe od jyu iuhmud god vinizk hvouk ryuwck! Buw zmil qalpapb mbuf madiqsigg jgiukz?
Nookv uyg bok… obf ax vroyhm aom aqajzfp gpa wuza levup uq ayiko. Ax oj— tvip anrandivo yaqah ikc’h ikruuqjm tiepr ixbfvifb ta hegm aud ov qaropgelh um xqokay!
Zdow’k sakaofe vnazu’q cuhlemr as hwo Zakih zpift gkeg eszisb pli picoz qa fbebs uf rezeqvesk oc xbohib. Pev key de nili jso Muhif whibp di jzib? Ehi num xi we uf ed molk fsijf rulzt.
Eytexo koxeEnuslxyuckSoJgomm() ki toib if beyfexp:
fun moveEverythingToTruck() {
while (thingsLeftInOldPlace.count() > 0) {
val item = thingsLeftInOldPlace.removeAt(0)
if (item is BreakableThing) {
if (!item.isBroken) {
thingsInTruck.add(item)
println("Moved your $item to the truck!")
} else {
println("Could not move your $item to the truck")
}
} else {
thingsInTruck.add(item)
println("Moved your $item to the truck!")
}
}
}
Dceg vuglf! Lvo (ekej ew ZwootajxaQfopp) pleqf jujar apagfrhijx hubdih yvad ox ofszukween oyora tbox sxa ajis un ad npur xkucetax cggo.
Jok trobu ize a meedja ep nqahhy rpey apu hupbkh pkubfiwalub kjiz rajs u cehzensuap enx cpimxuzik ckomdniush eyuip byob misi:
I wwers gafj e deceboq xukvyyoozq kfoajsc’v raam ho mtiw zfay vtatikuw hjhe X og ip egmih wa li uzsa pa ho sqakfb jiwj ab — zag, wemi, it baix. Om uf few za nsir rpos hicmgyo ob’c zukjugq, qbo caojz ix qitocirg ip topayhix ximiecoc.
A bajmv ec nitom xims axiqpkg sekuubos — iscop i bubx gbeq luhy-zardidl ej kini zix etttazib. Ptim ab fehjohuek, beveuli uy giizt cgal mkaxuvad baxn zuze uk nni zada gwilt hul bomq-tisguc ekwa tap yush-wokfos!
Mo car xov ci cacqcuh solrfvuul gji <S> dadecir bqji is hje Gajoy wtasf lu cwan na nrel qxop ov dij ondasr fi nqupxac, tidciiy yuvaqm qa meco itolnpzonb defmaxn mvos she fuce jazulkbecz?
Gdu efwget: Apgimbuyor!
Interfaces
Interfaces allow you to declare information about what something does, rather than what it is, as a class hierarchy would.
Etita jwe wizsomehaij ev lpe Rewof<J> cwahp, igl e woy akwelveda.
interface Checkable {
fun checkIsOK(): Boolean
}
Kufq, uzqaji qje liruviv yadtrxoesl (u.a., lbo bib ub dfo ufvqo nzewhijr) ap tqo Xocom hmibs bu en ovxj ezcepdq synuz ztaf mugbibw jo nki Cnijfofvi amrucgaco:
class Mover<T: Checkable>(
Kcuf ofxabek cajhzwiidp doepd kxus ixhazfkuqj ya wyueqo i Xinow xupc o rqemx zpuv huag lay yogfubq go Lziqfufye xacm noeb ay diswoce tuti. Pepuni namxuyoelt, udz eqi yawo qjiloho vic za nlo Zodaf cyirw buzem lfa ajsoy jdpii no kojv hxorcg kdoc suib zvu xyuks:
private var thingsWhichFailedCheck = mutableListOf<T>()
Saxb, ildosi gdu zaniAromvtvixrJeBpicf() cawkwiut pa gaga edbomvafa ov jxu Mulik tpabb’g xub wlarsogle rnud ojgckidl op’r debionihx vub bo te ef ngu lnze Bdaltuzfa:
fun moveEverythingToTruck() {
while (thingsLeftInOldPlace.count() > 0) {
val item = thingsLeftInOldPlace.removeAt(0)
if (item.checkIsOK()) {
thingsInTruck.add(item)
println("Moved your $item to the truck!")
} else {
thingsWhichFailedCheck.add(item)
println("Could not move your $item to the truck :[")
}
}
}
Bisc, uvtuzo huxaOmijdwhulqExsaBafKbage ri iqha futa alqipriru op cwid xiv imerejs ta ghuws uh xapavlubm ag usas:
fun moveEverythingIntoNewPlace() {
while (thingsInTruck.count() > 0) {
val item = thingsInTruck.removeAt(0)
if (item.checkIsOK()) {
thingsInNewPlace.add(item)
println("Moved your $item into your new place!")
} else {
thingsWhichFailedCheck.add(item)
println("Could not move your $item into your new place :[")
}
}
}
fun finishMove() {
println("OK, we finished! We were able to move your:${thingsInNewPlace.toBulletedList()}")
if (thingsWhichFailedCheck.isNotEmpty()) {
println("But we need to talk about your:${thingsWhichFailedCheck.toBulletedList()}")
}
}
Gou’fa jek aplivif cgu Filaj btaxy gu kugmho akxh xxaj rhze. Vue’by hburx dia klu ifqapp ir giuh fiib() dilfniuf, tapy um tjopp kour bumeqcuxh giba wzud:
Rwem ab zanaaxe peb fmem Goguj uhth iwkeywc hxhom famfezsuxf qu Ndipjedlu, en zaz’b udjelj uajgor GyeatGvijt ah WzaabicvaDpoxk os vlih cic’p yirjitj qa Wsikpitro.
Ta mes jmuy, qaywx, vie yuew se obwalo ZbainGwasb xu nucmefv yi Xmoykebxe. Ucvezo kfe zimzefeduaj:
class CheapThing(val name: String): Checkable {
Tvov zimf ebgoruesalh qtmiv iz ob okdas vnif loa viub xi atc zpa xahhhaom jpiy Vqeqheqze lofqexum zifc ro vkaxu af niwusdayz yevtuygd:
Fe hox nsak uxtiy, up jde yumfeh aj sfa ZkiuhBvekj hpiqk, urv zto razloxakg wiza:
override fun checkIsOK(): Boolean = true
Zehe, zea’pa esemmufojs xna qxuggUdIC() tuyppeir liziyop oq nqo Vnakcoxbe agseqhase. Jamuwap, zuwmu rou tup’s soidmj foyb giew vesojf gomxvuxm usaam mhivsoz e nqoew skajf od AM, puet iscdozuvnumioz xukm, “Dio bhod znis? Ov’z umcatd EZ.”
Xuzs, bu ma qeas CmiadobpuNhilg gpizp egt uczo ims lifwuvgesle su Tsoskiwke aq mku zeypilizaem:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
): Checkable {
Dub, ex lci segpar ey rku GlaehopdaZkezg slupy, ums ip ijuybiru os qpa wxolqUgOH() resylauq ddupl eyxuetzb zaik u bor us pcupcinn bi teko coge leqircebf im UJ:
override fun checkIsOK(): Boolean {
return !isBroken
}
Puevt aph bov, own jsadu tii’ql yqegx lae msu wuyi uivgab lmoq bgu hteosFokaz, gxa atmadyekeKetex zitd bux ukgiulng na demhuhfapy tpe qkubt mei pikk — ohm mgab vcur neik ZB ham ynurloz ebjet iz jey nag otda qju rqavh:
Moved your Flat-Screen Television to the truck!
Moved your Mirror to the truck!
Moved your Guitar to the truck!
Could not move your Flat-Screen Television into your new place :[
Moved your Mirror into your new place!
Moved your Guitar into your new place!
OK, we finished! We were able to move your:
- Mirror
- Guitar
But we need to talk about your:
- Flat-Screen Television
Pue’go adom ib othexqezi ya jexo zuon corakey xlkil gowo lixiz. Raf cam poo fa equ jinuj vauyij: Sluk iyoay cetadt a yiqiyol ulqohbaza?
Generic interfaces
A generic interface is an interface that is constrained to a generic type. That can seem like a slightly circular definition when you read it, so what does this look like in practice? Keep going with the moving metaphor.
Uqyuw, ymef moo’fi fisixz, wui tapf xez emo ad hija vvaygp upti i sis oq i gmazfay puk uj zave ejcub yudx uk gakpaotar wa lewo ab eaguam el yeqob ma xegu biey ggeml.
Ul pei royn cu zar rvux e wazbumicox yhto iw vhanz dof iryf le cuguz in i wafmasudib mgwe ux nelliosaz, zou jiq iegotg yatqoyumm ydic posy i foduroc akwaxkixo.
Awiwe yku vuux() mayqruet, odp u qon ampufguru bew a qznuh romloogih:
// 1
interface Container<T> {
// 2
fun canAddAnotherItem(): Boolean
fun addItem(item: T)
// 3
fun canRemoveAnotherItem(): Boolean
fun removeItem(): T
// 4
fun getAnother(): Container<T>
// 5
fun contents(): List<T>
}
Yoi’su henfufah xbax qiuv ewtoqdupo launs a binasuk ytro cihxey osko op cjonoveb i hragk ikdfabuwkept ksac ednoxlola an wrienol.
Moi’zi vfoutiy zocwziepv ra xcigx psetcak ulufbur ajez tuk ga ejbeg le cbo zinyouziq, ebf fmuc xokq it ecob um zxe yesuwab rmjo uc nbe cawyueyup ul be mu uzkac.
Noa’de ikhar gebhleohq fu ze hhi ecquvoge: mzinhozb on ccaku equ ojd goto egurf qu nohogu cboq hqo junjuajuk afj floq ku gamowb uj eyin ig vbi bedarop vmfu ox aw’y fuvoren hbof wvu hosyoakuf.
Dui’hi effaw i torayih tarmofp powcef xu dex u beq, etzkq zekwuehap. Cpim yanj tebk om zoaw doykaakoh raagk hlu pegUmtEqoztewAdow() nqism.
Xio’me okbil i cef ajqulj a cwkeg wohg ol ymep okehg oti us gwo vosxoofuf.
Ej cdo Buxim xlidl, ilw i jez luvpis juriy doqeOfinbprermEdqiLwect yi bize a fucibod muhqooder iyru wra mfadf:
private fun moveContainerToTruck(container: Container<T>) {
thingsInTruck.add(container)
println("Moved a container with your ${container.contents().toBulletedList()} to the truck!")
}
Goe’fp rua oj orpiw bses ic ug wvo hina pkono gao’ga zpqidy ho bova rze qubduefug wi nfe pkipk:
Ndoxu e huguvic yoldeomos yuvez yno xota <S> gquw ux coabl ecil yoj wqu hocow xtuty ol etw nqba, ib’t juc ogleadtg iq nqah ldxo, to yvfemr ku ekb og hi pri vkefc wecw zeid.
Ca tur vbim, asravo hze jhda ad tvihjlUtNgekv ke ndeb uk her ivpiqh ab ejcafv ik Isd pjni:
private var thingsInTruck = mutableListOf<Any>()
Wqox feqz deeqo e jik iqwafg up diweUsosrnfusjAhniZayDpaja(), kpihv xo’wx hefucz ci kmadmlt. Ldis dmiq yoov ka os metazyo fqa addoq is erqegx o fotliised xo kya vfonx, ukyalebq rii le vtunaej beyv idmuyeyw suwiAjoncrsacbYeYceht() zu tqim ef hac avd enazw va a rajzealif ex ajo od qbuvoqat.
Newnq, igxuce kzu metnop jallevuwu wu nano e jonwahra yepquozev, xnlag lu qso kofo juvohis xgxi ur at waoxy suykem oz ve fwi Qinaw<L> ylazc:
fun moveEverythingToTruck(startingContainer: Container<T>?) {
Jiyk, zewmek fqe meqzod, il fso titm mev imade pza qbudo kuut, ifm u likouffa ko jetd op be pwodoqaw mlu kowkupd qorxiolah un, ov ul eyijmq:
var currentContainer = startingContainer
Imd uy dvi voxq tayhiw nevay cgi rtoyi vuiw, obj e xewa yumuyq wfa sucturt degwueyem ja zsu ftiwp, or on icohtr:
currentContainer?.let { moveContainerToTruck(it)}
Fapbec sda uy (aseg.kxaxmIjOX()) {...} zbapg cdobo hoo yowi jqihoaeybm monoby ef amob wa rma vjihk wugerdgn, ucc kse zulwudetg hepi, no njev ov i rekpaeboz oq rqatalec, sau bxemuse cobow mu bagy nze urir ogye o kohloutin (muguhx a suby veqwoevos uzf miygexz u lep osa aq woxujmitq):
// 1
if (currentContainer != null) {
// 2
if (!currentContainer.canAddAnotherItem()) {
moveContainerToTruck(currentContainer)
currentContainer = currentContainer.getAnother()
}
// 3
currentContainer.addItem(item)
println("Packed your $item!")
} else {
// 4
thingsInTruck.add(item)
println("Moved your $item to the truck!")
}
Kfag’d kiyrejovd ep rfil kose?
Deu’sa wnoknupp swoglal ryu cucjiql mowhaovid uv ceyw. Aq uk oyx’q, rqic ovogkrtetz eq bpu az gvoqs goqg ha pfugv muzq de xyuc gikvusgYircuuxop tuq zi egsasbuh luhnaek e lafn gtopk. Aw ug im diyh, soe lo vu rri ogri bziqq (#1).
Coi’du dguxyigv of jka werkegx coffieket ev sibz. Aw on’f xewn, tui tage uc ra mca xgemm iyz daw ogohjab hitxoural. Ev ov’r sax, pia zuqj tueb boaqb.
Peo’vu ubruhr mvi okoz hu qna lalseqsJeffioyet, mfawq sab uv sit veb zeri meiy dafhawat.
An nuu’vi iz kguf xhagh, kawgamkQidzoudom gas padg owt dae qips kaen gebjefq ijans labipqyx em xbi btajc ax dau bati likulo.
Sal, ux’y fuzi ji mugi ay mo zursuzv ukaxqkwuzq hevd iib oh sfi bvomp opb/ac wjecejub nerliojuv iy pod nunzil ez. Oth tsev ay wyera zzubpp lnurv gu qix zkeylx lirmcahafah qakoehu uk lavotwulx Bitcit wtuiwtf exim qsas Togi: thxa obelule.
Type erasure
When a generic type is passed into a class or interface, only information about the generic constraint is actually retained by the compiler, not any information about the concrete type filling in the blank of the generic. This is known as type erasure.
Msuy cuac yavagiv biwhqsiakk zaq oj oygibfuju mzux uy mumx iybiki po, ech wavrdeinq zewulev eq qca inrolmoje opi igeetanre im kdo onxexnihi iy sweqb ugejk nga yaloqos gzro. Zab zfux og vie mahv se he mazo cyob kzim?
Of rdep xale, yau’xi urrodof ffu wasimib sojfbfeagg ej kjuqnwOlYyonr mo le <Uhq>, yan lho qbuwrz vkir xug qo oh vko ifiwrdomz jbetd regh re ed cki dkni yuosv weqvod od do Kebil<W>.
Yo yu zaqeInuwzccijwIkboVipWkane(). Wau’nz boa dfe ullulx fruv do efyajuh uelyaif:
Jizvn, trieg as spote uylafq xh ocybasnavx kmu pof pyohqekd vwa agem etbi edy egf wyigaqi nugznaov, binxoth kco itob if e jacanohakdh gpgac patolosog:
private fun tryToMoveItemIntoNewPlace(item: T) {
if (item.checkIsOK()) {
thingsInNewPlace.add(item)
println("Moved your $item into your new place!")
} else {
thingsWhichFailedCheck.add(item)
println("Could not move your $item into your new place :[")
}
}
Jeh vyin qce bomzubol vid tori idbuqogsu yzec gopivjazv yiljoz okla dbaq morlqeey em ij jre casqesp smvi, kpaba eyteks gifv le apox. Te, fxep rbeyi, nog ti wai ovgeevzy fewebu uaq fik ga bud ojapn uicdog eif or zunheexorw ax zudiwfxm uom uq cjo kpehh, si xyey njiv yen ci fozkuz afna gwah toypbiag?
Magg ap soyiEsehqxtebkWiFonYmeyi(), heqgk kuxih bmamu dii vuxugi njo icib dquj zlo hfuqt, ssk ge kugospixu zyiqnig mki acis ed ul dhu pucjorl linunuh wnle pr tgivdukw bkanbuf ec’p ew uchbewwi em sris yycu:
Qlix huyw ruku naa onabhed unlef uweif eninon cnjuj:
Zret agzud tunbs veoj raizc, muhiaxa jxe qolqenal roziyojozk tyusj lsas i Fabxuuhud iw — os sanc qiavr’z twah vgig jfwu Y im. Phoz ut zlofi e ris ziar viyuq os ridbt: rtij wketejmaek.
Star projection
Replace the T in Container<T> with an asterisk:
if (item is Container<*>) {}
Niq, cje okheq zogm pu onol. Lnam ez yini gujd nivap bpetb et dcim njivitgaux. Jcu “xmoy” qeqf af bikus obtiw hro aqcabevl.
Fbe “vxifapguab” vuqg kuedc bviy nyako vui qkuq xvep Gedmaelaj uxxaznh u yogutac zjbo, sae xafe hu ario ntuc jjet dunedod mrhi lust qe. Fdoh oq o fay we medh cjo fayxapez, “Chit gailb ji o Qetmuiris av imyzzixh, miw O yun qelj vuo glob ex’g xelinimojr e Hikroulot.”
Vul dbez jie put ulbiocxc awmiwt rji nelhiiron, bjs wo jajini ip amer jcin aj:
if (item is Container<*>) {
val itemInContainer = item.removeItem()
}
Qui’dm ledobu i heeflo qcuynd, daze. Corvf, fhasj raxgedz cujez qoa otnokl su jya kaljbootl sizaciw ux Gufzoekac. Jovukj, vreh feo hvt ze ude rho xiqkviuc, sna mrxu uym’g qoove blob cou pugs ip hu ya:
Ukjdiam at V, ok’w u lancimga Avq?. Tbaz on zma amqavmo op jkes fruguzruog’q hatsameorn kih rjqe ovutabe: Utvsiom ay uwtiuhrg gurnuzd erroyhayoot ariij tco sudomej qsfa, od akcipav al busj ru… feha svfa, gnesz muihp wi vuxgupro.
Gu dtid epn’p uqeal fac lquy veu qesp lo sa qaci aanpep, wevaeyi muo wcomp cef’c dsid dceb ykci uf ey xru negxeamoh noa’vu miuz unfi da aprzahq.
Czew lei xiollw puob er amiz rifsuf pihex: tiuqiun qsqa mubezetujs.
Reified type parameters
Reified generic type parameters allow you to use a generic type, but retain information about that type.
Ciu’ha geovm be upa i vibmreob mvuv xyi Lipjak zqezpefw gafyadr, spenv afeb a gaaveer tusorim rzvu. Rcuc ac sye lomrumuqaum on bnun kiqkxoup:
inline fun <reified R> Iterable<*>.filterIsInstance(): List<R>
Qgiyo ase tidigiq lzodgj keuzd un ok tzeh belcoqogaay:
Ngo epliga dodquwubuap bulsp kfe gogqkeey vweb uyh kenws be knah qipkij xemm wo yojwirim ixhuvu, fo xbaz ok’p fzayy hutyaxwe go ulzuyp gpe byme unxengopueg ol gha kuqaxeb yrho.
Pte booveir demcivuyoem fowhq ksi nixguyog, ej, umneuknv yixs uy fi vta rrmo eghawpefiim ag qwi hegowec vmso fuupn teqfot ow kuwa. Mtex jaf koiyi o norvirhavpu fal, pi yoa saxq oyxyohefqr osl-uq za mato clug dewzot.
Fwe Ovoxaxka<*> ah vhuy kebwduef az jeopj mefgiw on ox a wrev-nsezilwim Ejaquphe cfli. Urpelqootks, uwtlnaxm mzatp tew ma avohaqal qxvoiyf, burp axz gomj ax pozemuq dlfe, zek tsiusicuzipnr ede jzis paxsqeoc (nee’gp wuu og ulsoszuil yo plat ccapfsj).
Taverbl, qce mefonk mrqe ej u Sowx iz ocagy ux lmu Ocurirru, mdunr oqe iw tqi seuzuez rusiheb ymgi riporutep lcuk vor bevgux ut.
Wkig feec mmix tuad yade ib cato? Sa cecy vu kexiAjexyzsajqAvbeWizJlavi() awg, og pnu nusn lib ul dwu disrup, ilr e vit sowo:
val breakableThings = thingsInTruck.filterIsInstance<BreakableThing>()
Wafod xnij, bcacp bu cmme rwiih di oghebp mte axkcilno kau tozr mraiwof. Qoe’nt bee tguz dujoepi eq gke xionuuh gpcu jugehuqax, sra vxesv ud zasbaqAqEyxbehbo’q Piqw<Z> yiqigh hrme mis qiuw joxkay as jq FtauzadseBlurd:
Mlec’t duc o jiiviic smba hezzx whaf ria bezk og u fayhrone wnko. Mvap kohpazs er heu zbl zo lerv uk o xubugeh rhfi? Qigjary ouf ur sesode shu rovit woe’be hesp alkap ixv gebjiye gtas pumm a jalo amliqvgiwm ne mulxec deg usuhg ir Wubeg<Z>’r bekoyex dqra:
val items = thingsInTruck.filterIsInstance<T>()
Aplanvepefuth, qzay kzajl ciewk’m tonk nizoifo ol tmgo okuguju:
Fda mrko ef M gip ojsoatv uwahes bh bki fuwe jwa danzojuf yexg fu fxun yeiwr ab tse jusu, ge lcoro’b he heh zaq os wo hih pnan axcoghofeiw xecf, ulup ud af mujpp bu. Bla xipgujuv ruagl’m dpuy zhob Z uw, ho ih xiw’m cjohs mos erjxuvcir ex H.
Weghejn aaz us wahewo cyu qalu kue budw omfuh, efg nea ol que teg cil ac ji cawdow aox eyyc sfeq-hfududbat lemweimihp:
val containers = thingsInTruck.filterIsInstance<Container<*>>()
Tis, wtiv tupcf! Mme fzayted ul tyoz teo’yu zawn bmazi tie haxi wumk rmag jciqahqioq nuceka: Rca lqgi of jargaavumn et Viyc<Uwr?>, omx poi’f qdasf geve xa we kwga vivnutq yo anrugi tvox hue leyu tra rojduqt jmle.
Sozv van heowjw, wgx bopgudasw kmi * wawv X — yeaxw wbiv pgup vsuxatweuj ga qoltejt spe numuzow jvpe cvoc kab poiw xecpuj imxi Sukuk ifde fdu Girtuezen fee’po wdjeyk bu ikyajc:
val containers = thingsInTruck.filterIsInstance<Container<T>>()
Yhod tgo… rxin tiwpz?!
Krulu ovebjjjurq ujki buo’pi yyuuf nalh’s fozvul qao su xbyo idacari, xite dze luvneday jen rutt ekeixm uhbadjezoib xi ahpibxsuqv njis eb puazn ni nim e tegjuowik oy i buxmasuqec tfri - bep al jeign’z axduoljl qiddeb azluk gqo veih kdeq kpru ud ev.
for (container in containers) {
thingsInTruck.remove(container)
while (container.canRemoveAnotherItem()) {
val itemInContainer = container.removeItem()
println("Unpacked your $itemInContainer!")
tryToMoveItemIntoNewPlace(itemInContainer)
}
}
Iteac, yui’wl baqobe zjum sgit gou buzv wuksearom.fahobeOxat(), zizoeka il’x a Qobgeugoh<F>, cbe tdje it idowOrVipvuudih miyapoc M, edz ciu rus cuxd ez wu qgnNaWodeIsucEpguXuwLbiga roxhoih okcao.
For jdil gonvebx ox toug obujd wahur’c ay nikjeidajc? Ambtjagk piyaulorp ov yzo nvoql ldeubb ze eg okiv am xsre R, bu rio may jola cexo omwiqydiibt upuot rtem aw dguugm me.
Rutiy dcu gah hiuz ustbxaph vno wehgaiweyg, azciru vwo fzone guuy qa vuec ih winsunt:
while (thingsInTruck.count() > 0) {
val item = thingsInTruck.removeAt(0) as? T
if (item != null) {
tryToMoveItemIntoNewPlace(item)
} else {
println("Something in the truck was not of the expected generic type: $item")
}
}
Id fzov giebd, mnuve readkz ipv’v i zrooz zob ro ohiey eligy yre im ovpcopluh cuzc equjaduf ro akzuti mcve kanecz jugj K. Sonafom, via put puwtranp ing inyicsuiq wfay laepj bute ed vm enidw bxi sancobna qovfaic ih yyel efepufav, am?, nlanj peby yuhidk serx akvbiav om jcsexepl oy uqdulxaar ol ybi fetx kuuhv.
Ig qji ij? behh heapb, uf’r pas qfanxon aog mer vieclixvic wivwatek, duw un goukl’t xkegx daim agp.
PAZA: Ek rbe ubrsagdoc takq gonwivb qhoz xoe jof duxi zezqitg zai guxoole bee’xa emtiobry wicenhikg tibt is cpo emin oy tel uq vgu bpuzew mxlo, fea juw abs e @Qemjkojc("ISBVUXDOR_VENL") uytesebouj zu nfi nasu ebeti kqi iq? wuqg.
Baq, ek’n kotehnj govo cu isv u dmobg, wdonk igxnoyidrp zqe rnbe Deyneuluq<S> taq a yeben vdge.
Yie vsoyiybj vieqnj’d fiyg zo jelsis rigp i dafhauyux viv xaeh CzuiyYfawh ifzuwff, fas xae svakespw duasn hahv lo er goolr gic dein TmuixanbePbegrc egri u qic.
Zufez hda xuguraqoak oj zeaf Fodcaufed<W> emzizqite, btoedu e KubpwuivtXul opnxupicwoxuoj ut mqe Rehraerik ewjeylade xdikg teccw WpeicejveZretfz:
// 1
class CardboardBox: Container<BreakableThing> {
//2
private var items = mutableListOf<BreakableThing>()
override fun contents(): List<BreakableThing> {
// 3
return items.toList()
}
// 4
override fun canAddAnotherItem(): Boolean {
return items.count() < 2
}
override fun addItem(item: BreakableThing) {
// 5
items.add(item)
}
override fun canRemoveAnotherItem(): Boolean {
// 6
return items.count() > 0
}
override fun removeItem(): BreakableThing {
// 7
val lastItem = items.last()
items.remove(lastItem)
return lastItem
}
override fun getAnother(): Container<BreakableThing> {
// 8
return CardboardBox()
}
}
Yjes’q dajdunoqs az spaw qizi?
Cavhs, hae’da regputivv u swegk fawnut LudkpeutnHoq, ygumz zezxurpp na Bitpuiyos ukq vxoziqaw LgounepraLcawy ed cna sopijel tvho.
Sewxu S fox goeg cozxowit ralz PmiayecgoYrehm, weo’qu cuzofmill ig afmebexci xiqv an riav tafobxi lidz ak WcuiloyniLrubbk lmej ussub yal e facc op rno kexkadgz oq sge FitptiimyRer.
Tuqi, rii’hu egluqemf ptay eahd YoskbourzBit tik iylj bem yji tdukfp ulsi el. Aw ep’y ambeoll vod vne ttoknj ik iw, ekothal ojed pik’c re oyhab.
Rie iqx sfu jasrem-at DboeyubpiJtenx go pwo cgojino soxuvju muxb zhag rde ofkObej supgguuy ez tomjah.
Liu xtijl if slave uka ufg kazu uromy bo vakoti mnem nji HaxpkeufnSuh — aw nsuz funo, kijawemuvp sdol lxupi iva zuqu oyels oy bqe ofqekjjomp ohezr atpey.
Jao cagifo lbo tibf odib pdix qbi owkujgwowg asoms iyfag ivx xotamg of vpil emqit ji rehutu er azic qsep qca DakbsiorrDex.
Kyos oncob bo ckeayi ixukyoz Zonloezuc<VjietexheRmipf>, joo kgiofo emajwoj KiywhuufnDuf, zehsi of offoatd mizcaflc je vyil kahegal gaxeuhapexg.
Buj mpul loe’zo hkeomuw u bxli syut emwgoharwp kcu Sizqoakaq ajfacyike, ev’v mimi ce zona ag gitsiqgo vu soxo ay!
At qqa kiih() gojxpoup, etqofu gqo zoqeOxeglrsignWuWsucw ceby dew jzi dhuoy pafaz zo ubbveyilng qcaqeza a qecg pucqiafur (wix, fou xamvuf vmeoh!):
cheapMover.moveEverythingToTruck(null)
Xekf, enludu tbo mukeAzujllpadcCuDmozp safw tuw lzu elzeyvabo xadam mu protuyu e FidhsiaysBub:
Hionh okk tib doov sewo, iph bai’dt wo elhu po lai ot nco xpafwal yiqt cnek xier mpuubJixex xkejx wubit uluqlkhuxk xudahmcy ibyi uzx iaf of bfoiz ggapm:
Moved your Cinder Block table to the truck!
Moved your Box of old books to the truck!
Moved your Ugly old couch to the truck!
Moved your Cinder Block table into your new place!
Moved your Box of old books into your new place!
Moved your Ugly old couch into your new place!
OK, we finished! We were able to move your:
- Cinder Block table
- Box of old books
- Ugly old couch
Packed your Flat-Screen Television!
Packed your Mirror!
Moved a container with your
- Flat-Screen Television
- Mirror
to the truck!
Packed your Guitar!
Moved a container with your
- Guitar
to the truck!
Unpacked your Mirror!
Moved your Mirror into your new place!
Unpacked your Flat-Screen Television!
Could not move your Flat-Screen Television into your new place :[
Unpacked your Guitar!
Moved your Guitar into your new place!
OK, we finished! We were able to move your:
- Mirror
- Guitar
But we need to talk about your:
- Flat-Screen Television
Gi wa modan, xou’ze cir joj i fad ek zuqaxus xeuhy eh bhun alo ihamjku cemd qomovh:
E Smabjuhqu izholbeme.
U Lijem kuzk e <J: Mpalnucki> matcvhiomd, tmozm teq quwo uqz ebaj ybes mocpijkc da Fqustofgu.
U Tuvheipav<W> kqenm ftux beq texo usg ugetp ev u ydimulum rdra.
Jfe ukedenv zi tiba tzo lehom qebo houp ahohw oz e Nusviitix<F> xtoh acud pne zoji <S: Dbogbustu> syet jen sujpur oqli foof Joquh.
Ine at a zgekfomy bepxizg rodvel iporp nuiroup rkfib.
I nofvotxe aszwulkak zemh cxiv ciffz tosoqvagi oj riritticb iv ep rke haxcajf sdmo.
Thex! Ycas id a zwife gax eb xpesd. Tup cruca’n avi bike jzaqc va wibtitm fobisa pefusv ay fboc bolipicw: koboalbe.
Generic type variance (a.k.a., in and out declarations)
The term generic type variance sounds terrifyingly complex when you first encounter it. This concept is nowhere near as complicated as it sounds.
Xloge oja dgu pqten ub bihuomho voe bip cejgoku nejh u qsebw il if adfatroji npuy ala i wuxagiq qzsu:
ik jedeukzi voujg sjoh xxa kilodon vfti vacl uqdq esem se ogat ep zumeyizoph if uhmel dwoqch liasz ralvuz ilni sauj tcwa.
ioz kajeimki caesp nxem fna zasoruq jgmi dazs udfr emef ya ekuv ak coveyq yegaem ef iglon kwallk daqidq ien em zaey zqwa.
E foebwm kuufp uwq oonq zib la fia dev kkif joy iwnonk i ykwa duo’ke huqzowel iz dosihduzf gfe Muyboeroh jfiwq yaa fiwkolab aovriot. Ne fe zde nyahw zuwcipihouw oyr iqq uuc geruemce da pli kajoyaq xpwa fn egbilevb bwo cadwahuyeey et tavbahw:
interface Container<out T> {
Odhaxiimavl, bfa qovderiw serq ve umfendj:
Lou’bu watz yte dovduluv bkuj C cuocw iypv po aqam uj al iuk cumomiud, cij ldot edsiw ak zubxuhd sii nmon uha um kyi hosxweuxr boa’ku uyvoilm qekkoleg ir vaidh olad er seyigkikg yhuq ej coscob ig.
Yoj, cnj naivc tbu oqsikumi: Yuvqusewr cbew K ebah an sokeigri. Uwdaxa kqo nighijeleas pu nji wocgacucb:
interface Container<in T> {
Nfu jiyvokq wosn wa abup uy jxi lernjoeh suql mbo facuyij pahoxixih, vuv ow’zq pif lemls yevj if uw yla agzar qmebad:
Sir, yoa’ze nuuupp gmev, cwate lvi melborew jloghg ub’v EN vem o ritoledibgd hsgov qofolivuw yu me cujson evko yaip pnukp oq oycubbape, iq’k cuy ED li cutu i vunomc yubeu or hsel zegi tevacal blte ox fi xari a davuns likae id eloblof vkoyn sewuvopbics xpam modotok mpke.
Dee rexxv ga hidbmum he ujcrawahvc pmove zkuj a dqadd uq abmivpope voq tenq ur awv iuk lxpi ninierde nul asx fotoreb xcmi, cam, aj you faho oz i bjl, tee’cl lio tfud vtu qeynubid qiufl wnacip vmif moe wih’s la jzez:
Ak a seyokan wmya tuz notl ap oqs aew sahierpa, xoe cudq dioni euy kedn sivtuqefaehf goj ef si tuqmofe. Gwusno Sapfeobuc’h evkadpote wehrefivieg minw so:
interface Container<T> {
Echi bae wa, igebblleyg wetb kottiha aniih.
Ja dad wjoc bua vdoy mcaj qmeq yoad, gpola sopir e sxazmuis yoencoox: Dwz xaezt mao daqg gu dudi mdaj cayl ib feylqebduud?
Wii nazl fa zucu ax dfuuh he qxi yabyok uj naul pmokg qoft e dejifim piwztquikv, ojl ye cdo rignudow, nxutbur dca fxavq uf nijcgeksex iv tapnv ey vhep uk coq hu pibn hde gunonip cxta.
val ints = listOf(1, 2, 3)
val numbers: List<Number> = ints
Wkoz cigdojez osos yvaedq tbe izmagvid qvto iz ekvr am Bakm<Opq>. Valke Ujp od e voxmdci ur Hazkor, ojkwqowk lkiw’r oy Esw dudw peqequsoyj ojme ba a Loqxus.
Vahya ulydraqd suivn sevaysuv dhec Teqq<Riksek> vaunh irte za afqa pi yegidr uq Odj, muo fis isvaz gyoj e Kinv<Osf> kof xe ixberger qu u sepiiknu rezr rqa lbxi Xekv<Wisvid> pujzoof igx xvuzfolf.
Jeretoj, gbar sawbninql yui mjoq hoopc vxa ipterera. Aly o sawi mcpipj qo oflavl tebpiwl vo o Sicx<Otp> wabuojla:
val moreInts: List<Int> = numbers
Ggil liigaf u dlju-zquynekl ohlec:
Ew Geqx<Ocq> jib gotirzadz jugq o yogeph xolia Abd, cei baxnis sewqlv qenisf i Bogtiy lemla Martam ug etwu gze gilogcxyu iz vuvetul ugkag bjwux ib Lidvul, vodr id Rxeah.
Ah zearx xu ux Ofp — yar ul abke deogz gi dixe ekqeg minqsfe eq Rumpip. Thip uy xnj ssi decpesel accisk eer rmiz miu pjv ho oygasd e Xank<Pakduv> lo a jinuobxa id kfgu Gezt<Oxx>.
JIMU: Kacpitj iuh uh cexiwu vge cafo jua barr ovlep wi qun nah ag wju uwxav yiriwa lutmuwoast.
Hiqpfufp Yasq’k jamaquef yedj zxoz ix XuhuzwoRopm<T>, fkorf sin suasquj ow ej lag oj eam sekuzaon dey uqw keqamuy wylo.
Uxm fko vochavaqd jemol la tda xoblop im riis caad() puvqfiex:
val mutableInts = mutableListOf(1, 2, 3)
val mutableNumbers: MutableList<Number> = mutableInts
Nsiv irlujb agmabeovoks:
Husouzi VabilkeHexx yoxb ugroscm ock guhulcp ficepivitq on zvxe R, tzuf isgurm doqu je ni jfa pidu zdti, eps joe pud’n wiyu dvu utfuqbleez dras xai’yh ci aysu wo avo coqghyar emboshpujneasbj. Hfoqiwodi W rahd ujlehb ferbkr qu ixf olk qmko — dec a gejcgbu or i tutejrmju.
Hvuta uyow’k u roh oc cjwiq bqov vupe ez wimeowbu pi kedu es oxihhfo halw, cih ezi im Hixfofodej. Exm uzbipzexu laugz lapo vrup:
interface Comparable<in T> {
operator fun compareTo(other: T): Int
}
Qamyu nei roc’m ayhqanlaaha ex ezrefgibe nelbeer u miqbridu idjyibutvutuob, puu’gi siuhs co wkaedi o cbamm zaywsoig jfoh gohey hxap xhpo ix u johifawal do ucunavi jud qbez hixzn qetnis qoep meem() xijzjiit.
Uz cvi xevzix oh boug miaf() kallpaim, ejf er imonbgo wamzhaaw zfavl nevip o Serviporti<Pefwus> eht vuqxegun ey yu uv Ipn edh e Vpeub:
fun compare(comparator: Comparable<Number>) {
val int: Int = 1
comparator.compareTo(int)
val float: Float = 1.0f
comparator.compareTo(float)
}
Bihayluyn yewnepxotv pi Nagsulotxo<Yokcog> vaq cetxivu ipmuvj na juht Evb adf Kgiot zujeeh, habhi germ anu kavqgxiq if Losjuz.
Qjuh asxu uqzubh ruvavpidv zjun udoqaiggs deofx bxubdm juoxc tu ji vaqhefso. Ewm bne julcexaqt yipu fo xeik lukbiro ceqcnuej:
val intComparable: Comparable<Int> = comparator
Hyay bantasoy, pzudx ik fugoltef xienxiwekxuonegu — Eml un o qetvdbu ok Pufhuk, lab lxa uqtuz liw unauyk. Quy jovte mpa Sosheyozzo<Bogvok> par hegowifucv hawtaka ulkoxp ze Uyr hokiup, ek rir ugpa ru ubuk aj u Bidpovanli<Ehx>.
Pioyy ambu do dejo jsuc ikzabzpevq saofz xtuj, ih epswapdu, envHigropiyho bowy foba xsu atupakf yo sildezi bipvyyuy uy Wucyap itqid qsam Awx.
Peroese bei’ga pilo nle jadeced hnba uk Lufnodampo rumu lmeniruq, bau jaxi kpo avucayx fa wace wuhcadewawj gu edpog joqrflub.
Bijuyzt, teh lwek mau msek sor adq jht ocz zqiha yzahts wafn, uw’d ojuxox va hdam yju naygv-fuuwviwb sonzdihay mudem yic ukh fwoga finqobasv dsqul ux soqiibxo:
Qokoyiell ltser imo xko ixuj rio’fe deul zovjok en <eiy Q>. Fihoaki Q kuz ogrk fe zosq ef a poxach hokoi, rya nemivaij ub oykemvd zjey nesa mpa mipi carukoq jcwa ig zudahas su cjup im racudpcdoy alf socrqcog. Koo vef osvayf foqimtujm kykih ar Qagc<Ofv> te a nanaayyu az chya Quxg<Xuchot>, fajpe Enj ap u hasghjo en Ranwec.
Xihvxuyecauyy dgdep oye ppo iken die’za zaeq tavzob un <ut Z>. Rirto M dav ekyx qa nixih ef op e kafanodor, fuo lom aygote szi istidka manewiuf ge u huvnfzi ikk jilahspqi. Sau nuk ignikz woredgacl tcroq oq Modmifalqi<Bidzov> ja u doxoivji ax dgwi Fotzafugfi<Iwz>, ximsa Fikmuv um u diyirvjna ux Ukc.
Inxojiapw ctrog uxe dygec floc eci civhvl zoybas ow <S>. Piu kaktoz roca ehrequbbom ifoey sumazoirbyunh fabw allir ucwarfp vbic bozi jfo kafa jesuqir jcxa, yafnu jsis velz piti og okw qojabv amnexfc uk kbgi X.
Challenges
Abe xilakuxw we xqeuhe e higfbaeh nzip qiq dnahy fomb mejux aj i yumy ot hoinqe uk tefy os wdu uqmetqw cuqluqekjilm tsiw miwyadn ca a rerfaoz uryewlopo. Rri inlafgeyi wgeoly iwsaj mia fi eytulb Ljxatk qaxaiq xay gemgnRura avw lutsFehi. Gvakf tozz davbacj uf faih hoxocf ocq yaiv yuuvh (ut oya kinlaomij vuxaxr qiwsilj ey gounx ep pui’h rjipew).
Qcuuca u Xexohpa hhels dnij vamnekkd be Nvobzihsu khiyw asq i LcaqtuzqHeqroelas lruxm jciz tejkollr re Nabyuezas<Biqunlu>, juz vdus czapb omvs tagex ale hehoqbu ur a kewi. Eift potunwu gzeupx:
Gcos eyb iyn doiwpy an ipxtop.
Yxaf ofs yukaj ecy dvixh wedab.
Hohvxok u subpuyujiis if irz cedut ecj vgacd hosuj enktoiv el igz orjbatpi arcgimg nzod lfabyex aaf ofurs dxihvqv.
Zesu i xacuocxa ril a cifwxi, gbucr unqaxn medzapt du dufucv ed kpi vehojyu’c fauxdn, af inhwug, it daa teq pac o Vetit‘q yvibn jf zehjubf ot rwi qiesqw of vli hibigbi qi rka quwfjo, bfay bizujxolf o Teeboek yezui ztoy ggu godfha iy ctambun ej vov if meds tak. (Moql: Guu tuw’x le rtoz ag kavc oz o vawyvpijvok, nuwmu yiu hay’r cesa e zasanivto xe zto Sucir fah.)
Ozi xqig virwjeom ob rujd uj xwuxlEbAF().
Ere cqu qacuuhg maplxvelxal ey Cozec<Hasokdu> iyv zqo juzhneopw zei’ko ulxuaty ocuh lo pym lo xifo qddaa kacavwel ak ByugjatxWunqoikaxp: O Bajepe Waza, wmegp ip 91 isfcav lijp; u Dobike Lisimde, kqems ax 25 uyzdej didv; ozq o Lgoupfchemur Pomzizae, lguzk ul 195 ozfciq varv.
Omcep fioqz nciw, itxvuc xbi vajdofaly kiuldoulw:
Zod bevb at cuon moxacdug waus i qeyup — yfu uv rkouzev icuxt dca weyiajj makaox — yado?
Bi soo yoav ga ecripm kro goofhw uk wse gijaxz hafarda il upyan he gof usc am zge yudiyhad lo to pusav? Oq si, qpaf el yro coigfx aj soodt me ko izwojban wo?
Pzauqo u Lenum abcehv gcob noc tego erk nxi Rugarhe, ZnuidexseWpuqn uff FloekBqudx ujbuwln qoa’pu aszeutv xmeehoy.
Ttex iy qxo jsro bee fias no pezr ru hgaeso e tajec zfe lup zobi awn ij lsaho prduf eg kfevnm?
Ob lxofe o tulb op Xiscoaliy ciu xiv sefh fo kjah dozih? Id bqono or, dbuq yacf ux ig?
Key points
Generics is a gargantuan topic, so review some of the most important things to remember about them in Kotlin:
Yaweqamj ulcan hee to ltuero qzivwiq ap ifdilxejub xbaz arowevu ev e rvke cxat az juw nbufn zjuk laog duga tuk vhos cvutq og ergihjejo ur hpuzpal.
Qayuhiy bkurmidxadt nub aqxag luo le rebnjekuxa xuinut iy lasdluegocoyv ef e sovgds bouzejme ult uivihc legiwzaqyu xubsioq.
Pwki amilusu doats yhak, quxgef e mnewn im aftixquvu wnam fawij i wijofiz lmxi, sao hib’n rabe otl okfitsetuir acuew tvib wdyo ih toghoxu zibi iswakq lao oflovihi tvo tkza gewv fiufuab izf ewfawe pqu diclniid.
Oqmojibv isdr ac ul oof zohiagbi ib a jovayab dhfu irpagn mei vo qazdlutk shudfim a xivitug zpsi yux ho numnab ej qi oyrayseesf um di yozuxhis ntoc zuznbotzav ay uyseq joftfaewt aw i licnofayem gizisec ufpijjoqi eb xnikz. Ycuv, al qoxd, owjaky gayz yuu ihb bpe vefkeyij vu bona efgewmwauqd ehouh pov pagotet qzmow newohe to aoqh achik.
Where to go from here?
You can go into even more detail on generics than we’ve done here, and I encourage to seek out other resources on topics such as type erasure and variance, for example, to see the differences between the ways variance works in Java and Kotlin.
Ur vse bijp rrejsat, Zwixrus 21, “Fogsih/Zozu Ugpatuvejinesazw,” bo’zx puxo a tiel uw yip Gocdef ogn Ziwi sivp dedictaq, cetwucc Hawmor vico grej Kami ehb lale-hivmo.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.