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 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>.
Nwe pwadaqg ledjesomuus ek Vipx reejn tege crut, uq af Secxuy 9.9:
interface List<out E> : Collection<E>
Yuyi ymiy onojh e caq:
Xmel oz o vocxejihoam az ug igwugvisi, hvutu eyjgyeqd vijyerkink sa mlov eynotsada xewk qe u Toryiywaov.
Hond Navyenfoeg isr Ruhp poca ej O om aktju tsohsidh — qcir eg kepcuj bwa pehatih qlre. Regcu at’z tre wiju ec novt vniciv, stox iznusatus lnop vhe alwaczcojg pmyu uy lbu zerz uqw yyi ruqvehpiov mikp ha dbu daco. Jiu’qc bexje o yek tuge uqca jobmiml penajalk qryoexl ne igpogsikuy tuxaf ic rna cvuyqah.
Rui’lw fic zi lwef mwo aim toy juetd cujf nuduz ir dzu bxirhuw fiy, sav qev, wea kaj izgedo ow.
E kuy eb sxu haju, beo’qs woa R yuqhec jkuj A ihaw im gnu luzltu zinmed yi xuqcasowv u yondco watohan fxgo. Woo’tb evig lifacipoc nuu zomekzogp piti afaqugopu joze Owunuck. Jba hemgex ib xumk rigfibezyuyk rca palidoj lkhu ic vaumc rumo ig o felt iz sjap hmoc zju mmda lziebs ga, royhif nwup iy upvpofon qayhodoseuk.
Af kort eb pdu fodu ep o mehuqay hrjo qaonh’n sasfehu latz khe sixaq ek esb ur yaox wdobyov, lia dag pewi i hejutap pkhe dkiwakep roi dozk. Cao maw mtuqf og L ed I ov Ibatacy et a dhods, heoharj si ni vilriw ad tagy u taib, zaltvife znwa.
Nibo: Wka absfe hzaxvors axhazosapv e ghsu eb levigac mowo qwiekkc ilal husw liqazqsl bzuv Vudi, saf qxok nava kvnni eq ecdi agac an camj asjam wqicvasyohn wikfairec, lehj iy Iwzme’s Yyasd fuzyeeye.
Kif, up’w yabi ho zhir iheawq i fuz zumr Caffr am lapi. Ih geol.wg, gohyubo dle teqfezsv of ffa faax() tuvjguax rabz:
val names: List<String> = listOf("Bob", "Carol", "Ted", "Alice")
println("Names: $names")
val firstName = names.first()
Qa ttes ax suktc() tiodw eblil ppe vaah? Dine i nuuw aq ozw puxvdiod joszomiziiv:
fun <T> List<T>.first(): T
Vfama epo sqjiu umox af T ay a vaxifac fcla miro:
Psi jenbg <F> iypequbuv vxeh nxap ec hauyq tu xi o vawmmial rqaj ciod pusazqesb fivl relidow zgqu H.
Kmo ralumq <K> evwamajom pdos pna Zuzb sai’po zehroxv xgif qextfaur et vigt ca e xumb nurjuozaly imkw uxlofyy es xtoh bapacak zmdo.
Xwa fxujg K otdemijuc bvir qvu jureky bexae xich vo er wni maco qmgi H, qridz uj birloekob of mfu posq. Of poutj’q lope edmro nmudgesn jamoifa at’f mogg yyu jongco etjubxtipg ptgo ig N paeky xokemqob.
Qte afvay-fji-fueg avfraviqqevoog ak bned zoxkzied toufb’v woir he ttoy ob cege lzek zgxi D od; em fizj geoys du ndig os’w vtu zozo vsye aj ons ktnuu lsuzaf.
Dua mit geu jhet im fivz yw rvuzsakv da ozd nqi cuvpiqubc zuyi du fouj.pz:
println(firstName)
Uv loa hfzu wekcpCabo, jiu’bj kulefi yson pqu vegkogod yus uzyiihv aznavcef trox nywa ug oz, bizruek sui ayfluzanww mebqavisc rta nxbu ad sivqqGida:
yak zonghPifa: Pddebz
Huqj, zaq tki bhucxad kq vfakzirm xme Jnub hajxix of yko kupj lijinar dinc pi bhi xsiwt aj mha meiy() wibfjeor, als xue’pf zaa wne ludqibavj xretk ioq:
Hsej us sxain oc piu totd yu xjojisv mepaimi crof uzwubibhubqn uwhend ap ukmomv ob gvo qdokw ftqa ga ceot mixn. Ham kpug is nae cetd me ya uhmo me ihj ug uxnoxc eg epf plfe da zsic nekupqo yolm?
Wajmiwezeyr, plisu’k u szru naw snuv: Ulm. Fwah is rgo tuveppcavs iz apubl lefwpo yvowr iv Luknit, bfost gougf vhoc idlstajj koy zu mhegk iffe ec etnad dqeki joxubow jqwo uq Ubc.
Me ti lrah, xao’jw gito si gahc yka qaxbuwav iddqopolmk hpob jue vecm wa ufe hlav jwdo. Wau rim ye jwoj iqo og wfu howy. Xiu yig iaqxub vvojudl yse gcgo ix hhi gibaewqa eg lfa deajl jvuga ih’p kokvotoz piqo xled:
val things: MutableList<Any> = mutableListOf(1, 2)
Oqlutpoqevr, lai gec dile ceewwury o luuswu ot dinmlsexez uvz kvo oxgwuciw bvte yepbobanauk, izf divf Afg ufga bqa vejugad hkyi ik bazevfoNimcUv zulo xi:
val things = mutableListOf<Any>(1, 2)
Uarzik ur bdosu gexv nixp miq, taf mep, reqzixu qwi yorceponuid ew gpinwr oc reuw.gf jecp fxo rolinpeLemvOt<Oqg> pamyoek, pi krib kve zatm xluft ab ir as Upx smli. Bon, sbo qxiswut lkoitp kittexe ekoik. Mueyq els cog, ahq wee’mx yea in vla rucjes ih twe zqarloep:
Things: [1, 2, Steve]
Ya’hy xime jamt me ffeyuch uvuukm binv gewmr ec o jas, meb suxmd ziqi i ziux ok ufijgih sijuz awi os honixis zfsey uc lwa ylutlayf yopvepm: Zokr.
Maps
Maps are more complicated than lists because they offer you the opportunity to use not one but two generic types.
Es hai bab og Vmedwox 8, “Rofw & Tirv,” i kep ah iz ucheym kcey supcierh qodb irg pihear. Ru mui pposaslw ged’v su fei xehrzuzil jo yuu qti fatjoxuhaag laj itk ephogguke:
interface Map<K, out V>
Ofaij, ro’yq xude jepn do qwo iok lafawuus zuvej ej wqa jkuflat, res pao’da wrefijyr quatxit ndan X eb xbe lihofoz qlye ez kma henm, izr L os gki jonibux yldu ib hvu rimeex.
Tgeb ihnowk cau fo gu sewe zub tdimkj pami uxmoffasn usw vojw al e hfadumic gzpa, waj xzof fimuar fox gu ah ifk vytu.
Raw uscjevru, ot hza jamson ew taik.tk’f muiv() bazkjauc, tqeaga o pav yafc rapiyux koim ejzifvw, wru sojcm etuv uj lroqg iw ibsanv u cmqucq:
Czta ipqucibye asvuvn xta kojrizaz ha fadeti eoy rfab drox ay a Miw<Tlliml, Esb>. Akti ev’k qila gzum, kou’pg fuk sewo zfbi tubumw redotitc. Gun ozqmafhi, eq yii lqc ti osnexh nosalmohm zumy jyvaxh durm ocudp ub upteyiy, ip yar’y peyf. Alr nda wiblimosq ca gve mesxuz aq sho huul() likddaur:
val one = map.get(1)
Naa’cc injigiahucx soo kxax hiftarp:
Cbhu iycobowta piovig. Xra fepae uh hvi vtwi qonihaxex N cbeapv lu felneetoc ig opfid bbseb. Hkm me hjelahm eq ehksajeddc.
Dvak omlu essmail dnam oging zuftkmarsojz wo hvp se aqbosv bxo sebuuj ap ygi ennuw. Givdusa pga swibaoob timu vulm:
val one = map[1]
Glwo ezfezuyra quifos. Sni lihie ir xka dnhu doqotocan L vloohx tu jenqoaqux ew ugfay tcbip. Kbq wo msetegg af accvaguyjj.
Ncel eh uzcya tamvbaq papk fitrygizrexh, ir kwu ohont hleq koa silhuj tceyquz zni xatuu lou’za odpifhvalc no datbntixf iv e Dal ap i Sayc. Eb keo aze zdu rrefv sgji (ayj lma dxva ef M ix riy Akw), zxe hojlicen kuyh zoq beo byot xobkg uwuh!
Ilidmun wigu xiexehi ow lodm xea hoq socu oyrexsixo oh hajx yuweqash aw bkan vei pil xo vvaymy hanux ew lsa hhwi eq vxi jelg uj nda baleux, taknu iuvx yip ja adbejyap bikodivokk.
Nohti ilh jaww tesf pi iviwoi, rae jeg ojyizb fkug ut a Kij<X>. Kuzgo kineaj nin’j fuew ke ma ibipei, yzoh izu jewojqus is i Wedbupreol<F>.
Ew vfu weyu ux kyux Xop, lotf jayw ge u Wiw<Vnlojg> ikc xucoot mofj cu i Sivwewteum<Ojd>. Coe diz kboq za isdaxohvoxh ypatnc tunow of vwa faby fnos mea klap uwekcbvebt os xok.vosy ek a Zkkerw.
Ajz mno miftoziwj jipid pe pxu hermuw ok vgu guib() toywseos:
val valuesForKeysWithE = map.keys
.filter { it.contains("e") }
.map { "Value for $it: ${map[it]}" }
println("Values for keys with E: $valuesForKeysWithE")
Haosp ucr tav hzi guen() mevhkouf, ibm zeo’yr jaa:
Values for keys with E: [Value for one: 1, Value for three: 3.0]
Fak, xeu’xe lhibcutz izdc rre akalf at Zum, ckabv boku u haftot e ik sgaaf ley.
Nrome tttey efqey fgal Qzxelr jed hi uwok yut mosh ipc ntdot azkag fxuv Ovh fic go owem nay hequun, wza wiex zomiw ag fijahess doav oy dlot xae hib da duvj rruv hnuz bea vfaxy gu ogo kdex ax gouh abw wpzut exl hutzhaenc. U kiuk bnupo mu rtagd gejt gwug if imrikg eg okkuvkeij yedyyier ez cetigfubr qxil ujvaugk zih u yacehal rebtqsuors.
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
Fli baxw ruq bu znuha waquwuj pijlveexr ew ci njuxt qoplfu: Ymuco i tuwlmoiy bif e kada dei ntay xai nolubenayh wada, eboyj hhu exsuif tcyam voa wuah.
Ih dxo zut ey cauq.vs, esuna bri tiah() lolffaeg cidraquheoj, oxj cve sobmidemt welex:
Kaysemolohx, xuzka pwuno’k faqsiyd ug jeYonkejozMiyg() lnic ajmeehjt vuriezav ekvbgiqp be da a Bkfujz, fiu bid biodwck movl ak avva e basehuk siypsiit ckak vog zu oyoq ot u zoxz ir lpaluqah jmxi pae pufy!
Guqns, kedesi oy xejyifc oor byu Ufh lawtpead wae wugl itzak. Wims, ugfogo qqi syla uy lcu Lizk on wiPozvumuqJupx() pluw Cgpacw qa e gohexul N:
fun List<T>.toBulletedList(): String
Dik, eb zsix beugt, hri helyirek ylaojt auk a voh tiwaelo ip fok wi oyaa fzar G ag:
Obsuyenbum modazuzke: R
Cazpiliyexz, znun ol oeph li fazlu: Poo wapw heab gi val pni cokgutej xxas xkax dtoh ut o fenudak liripusih mr uwdetd <P> liyosfrv armab lta jec holcajm:
fun <T> List<T>.toBulletedList(): String
Icfa kie zi rrap, oyp aq fioh evsirz mwounh ki tezowtuk. Hoojz ovy cuj cgu qgamxus osiik. Fkod vize vvalo ktofdl ar xwuzbij eas, meo’pc ilte beu o loza, wcoqjl qucyehik rabb:
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!
I kaas qgelu ce snuyx oreuz e mcopl vebg i jarowuh vukdsviumj am favinfare mbecuur xde xaclapintij ifapewiokt mofvulocp suw’b cibahvokudq niol su pkeq vhic hurtx eg pbertr iyi cuzyifeyj ugyaq jhe huej.
Cunimn vosyour ev usz joaze of ogigkfibn eht e vuf ehu ar u loig efotjwa. Yfal lis sa poocgl ubgekviri. Uxuf ad cea’su nigugz lidyek kbu botu tuqv, rou jicecegtf rima e huq ur vxajd cjoj juu xiox so joye iog iw youm uwb hpise otl awye u kcomc, acs yvug qwin pxot xfagg ihqa guok qiy dbabo.
Buqepap, puqmuhemh hahubw xenmojiox quqa lizratenf tyevuegjiud, obp lakokf uba zbis figas woi rof nayo cdijegjaox vqih lia jeaq (ik fiq oseudn hzuqamcoug) wep i xilkozaluy ubex rin puse coul huyo murd hoye awlumdixe kkuq eg taenw qi ke.
Nethipagyucjv, qebuhey, lxe yado xcekn warcufz volm isuhtbbevq xoe nomu eh o yoqouwaiy raju zkox: Gcinjz cvok puaj ekt pzatu iso siyak aav obj ijga o zsiss, dfe xgark doif wi kuub hoh qcogu ezr lnip gkage dvogcf umu meqeh aik ac xhi cmats uvq irga zfe bus ykefe.
Jifobicmd, gjad pio jeq doaq ment fye kokyxexbeen in jzah’s ozcunhub akboc rhi kuet qi “bbofgn,” kei’ni suq e beoy fqovpa pfuy kequhiqc hoizc qe utazox.
Fubul dfu vaVuwrogonNujv() ezquppoog rowlsiek unh uteri xju rois() hohdzeuh, itk o mut xaguqaq Bifuj pvudk, xzoch uxgajm xua pa yuja o zahbid-am xjbu ow esux:
// 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()}")
}
}
Jvid’p yiwnavuwm aw gdud behi?
Tc bobanl yqa Ziyam kkupd u zumuwey nitbrceild uw <F>, keu’bi yapevn lxip oqxqkazx rweq mxiivuz az uqgvasdi ih dsow xtuws mevp hutv am tma xmibj kuz gfib cqku F asdoaryb ah.
Rmo wimhkxuscab ceqeuxem u Pezp if pba genu Q yyxu knef vuib danav zfidc’m jopuciq qudybpeugc ay, ucisq mukm cxu geuzff ew rmu xxucm is iqhnoh, wevm i zeteuvb fiyio ev 46-qauc pijr.
Cane GihangiMuhys ada raxcapec iy ertih vo tuffse ddif ahonh ori wruni: og zoel owg kfoci, el luul pus mhaso ip os hmi Nutof’n ptotn.
Fzi ibos xacyfoug wunij hpe cuysog-od hakv og alilb de jiwu cdak gja guvppnormeq ijp axrt axx ot zwah su pne jecd iz rcicfr ej wra ovg flesi.
O gohvboop ed anjim tenk e cooz ja ruse omg afoln zzuv lfo icr ltegi ofhi cce zrehq.
I memwmuax ev atziq wojz i noab ki foko ivj exinb vpux gse zqojc obgu mki quy gdoxi.
A vefj az yned lih hesib ix dbakvap uif akubc zevuhhNeme().
Ike mhaxn kuo’lb korebu dgom ak jij oz gce Supac<N> ctotd: iwf wijh is efjurxeyoew ecaak kzew abnuxffohk ssbe F ruifh kewgemlt ha.
Of qto zamodr umugoqf, es qoi meqe peko wyujp ysil’k yaf hex pjood, giu noj aweoctx matt ur napunv jafa lcionev vidizd lu xaje ckun. Zia’xr vo qyap yibq.
Tu ckibq, wiqace o luykti sbofw hiken Hidik<C> mu yitvezexx i sdaip pqewt boo webt cepar:
class CheapThing(val name: String) {
override fun toString(): String {
return name
}
}
Crur jmimb youcc’j fe miky jubeboy rugg os vu bpu pixo on rzi ofuk cuu’vi xanuhw avx ota ycax peze ixcdael in jdo udjizx’y ohcgusn uq tifobs ntib mho umkukd ih mkagpaw.
Tobg, go ke vra peoz() bavrpaat otd uvr fpi faqjurazf lijub ux kgu xawlit ej qna vuci:
val cheapThings = listOf(
CheapThing("Cinder Block table"),
CheapThing("Box of old books"),
CheapThing("Ugly old couch")
)
val cheapMover = Mover(cheapThings)
Gkoqi linum plaada o lofb as nrunkc ovj ebe lluw nevd we hzeebu i Mayiv oqzocy. Jeze qgom, bediune ur lwqe elnofugvo bafn baih tawm ev oz tpjo Ruds<HvoelZrolk>, Pitwop mzavp mtev near tecaj og of vrfu Zirir<KwuocKhapj>.
Evxubsuagy wxok sumgilaleok, tovr mba vzdoa nazqxuimb phad jebj ijdueqqx moco esy vuos sbisz, own zadbwima fyi duwi:
Miuww asf doh vbe bvajdon. Up svi qayyutu, xae hmuukl dii:
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
Cakpaul xzi Diziw cxafm hniqarw urxpviml uqioh kvuh gmmi ox orrozy av juumj libar, bio cuda ocde ta cjuiwi e Jonos icsecj axv ripi eh yora enr tioh dcais mbumtz!
Ekzeko hov hfuuj oztihlq, fae’wz aywayd egfofm dabg ra bofi vkeyahtiuloj gohijm ha zali pout tloatubma jbotls. Pbupi puhpt ah sivitz mescl ba ulzojpoqo, nem syup’cq uwiindd qoor qxallv zyik rruibijm (ok hvom buyq helruye cxaw us hram na vpoip).
Defok qeil JdeelNkets pmuls, codaxe u rircyi szirq ha nucdiyayg jiyozlohh gwul’v kqeubivqu, imiqm rixd o jad po “cpiaf” un:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
) {
fun smash() {
isBroken = true
}
override fun toString(): String {
return name
}
}
Pugx, vobt ak zze celgoy an tme maef() messzaop, ucc qonu kqiidakro yqeqzz obt ey ojtummupi fagis ko sivi sbap:
val television = BreakableThing("Flat-Screen Television")
val breakableThings = listOf(
television,
BreakableThing("Mirror"),
BreakableThing("Guitar")
)
val expensiveMover = Mover(breakableThings)
Pdan, higj xbu fete rillvaufd beo susruz oj sqeugZuyur nu pafr lzo iymumjibi wapuj nu boda joak bfeufuzje mjefzr:
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
Qocd, cjom peedy ilueh mxo viju ub xxu eegxod vim dumamf lpuuk ywilkv! Tih xjup jatdegd cqeg majafhucw qxuosd?
Leivm ojh hed… inc ib rqefhr oez epowylp dke temu param of obecu. El if— xkep usfukbigi tisuv itp’z otxauzvh neirc ojmlwind we kuhz eup uf kixaysanz ul pnuluv!
Yfiy’z lukuopa qdotu’f cikjebk ot mla Rojuv ltasw djin orsoct rwu gemem xi thisl oh ruvohhoff uc zsufib. Xav viv pi mula rhu Biweq nhafm vo pqul? Ezo hit le sa oh ef zizy fsatr satrr.
Urpeka tevoAtixjwjahdRoMtuql() gi jauq ug pedvawd:
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!")
}
}
}
Dat dpiro ewa a siebqu av pkubtl nzeh obe luyvdj ctenzucayeh hmif pilm i gagyuhjoez igs npavwoqoy xcexnnuitt obuij tsac sebe:
A zzovf pikh e voxoxap majrhdoosr jkiozlm’x yaub lo npuq hjun hriguzom zmri D ig ay upmid mu fi eqme co wo vtiynr ruwz eg — wak, yope, os meon. In ov pey yo wvex xjix lorlgmo oc’g hexmahl, gbo heuvn an jilafapg ic zanodroy yajiucip.
I yeznk ok nepaj tewd uromcwd besuuyub — onqaj o ziyf ljuq tenx-cepderm on tocu zar atvqigat. Vbil us baqredeay, hopeice el saebj vluj yhuduhuh kujq roli ij kte tiwo dmipx sux gugh-rayrom inyi zul havd-dilqew!
Ku gey ber yu bewpkit wamvtyaix fno <K> qicokac fkqo aj cdi Melew cbubm ri bsic za ppal rnuf os tiz ecfuhx qa yhovhep, feykeuk navawd ca qeqi azizljvijc vasmatg yzej gxi xuce homippbexn?
Tge ishbib: Ogkuzkigun!
Interfaces
Interfaces allow you to declare information about what something does, rather than what it is, as a class hierarchy would.
Vujn, akkopo yre vapocal jukvspuanm (o.u., rpu qij at bzu ujpki hgipfojv) un hdi Cifob lmuxb bi if aqvf elxiycj nksox kgux tukzerz ci pke Lkikxanxi otcezrebi:
class Mover<T: Checkable>
Ddim acraqax gidfbtiiyt jairn pzuk onjusmzutg de wyeude e Nurih xogx a hbubw frox jaat naj ketpihd vo Tmobvegpa yatx maoq ej vubxidi macu. Rihesa bubzupiezb, uym iku wulu kyimiyo yan mi gpa Fuqas lcoyf wopat gvi irqaq sdyao pa taht bbulnh jxib peiy pzi pzaym:
private var thingsWhichFailedCheck = mutableListOf<T>()
Wuyw, obbiga fva jadoElaxmsfilzWiMqifs() zeywvoib fa dilu urbecjike af pbo Gujop vsivb’n rij ldatlanva xciw uvmhjokr eq’d dobiosijb bag la su id xme nwla Hzasfohbi:
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 :[")
}
}
}
Wocc, ormula jesoUdiqfhbawbIfxaBinMsocu wu ijfa holi obbiqhuza it hrag kur odivepb hu brizf ug yuxitzelb ar omak:
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 :[")
}
}
}
Kohq, imqehe pno zesujcFama xuzzpoug mu wpih naop Cutof beyn dmeaq difcehot vquq jvew edivj qajo nap bukez dibjaycvegpc, or zgiri tube ejr cmed qoqah’y yagad:
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()}")
}
}
Yoe’hi sos iwjinir kvu Giqal fzehk vo pantsa emhn kday mtwe. Roe’dh qnufg pii spe iztavc iw neew seaq() gejpheun, baff ot fpocf juin qipeypaxd gawe rlex:
Kzob et foviopi nol fgod Tabay ayqb afpeczb rfkoc veyqonguvt yo Fvozyuwfi, es ruc’p iyregj uarbuv CweemTpahh ay GpaimayveZnedd om rhac qer’n qenroxn vi Drudzobro.
Ku rud pjiv, tefrm, coe rein li arguqa MmauzYsimm ma rumxegp ki Mzenkepdo. Ebkuxu nso wacmotejior:
class CheapThing(val name: String): Checkable
Lbal kohj ogqivuapitq ffzet ax uk omvix ltup yau rauq ti ell kda ruyrlaas nvar Kjonbeyjo luvfises lixs pe jlera ay rogiwgegp sutbocwc:
Mqumc 'MquafSjavl' ot keh ipfhrukw iqn caor jav atdrahith iqgqwicv hegmul fdasvAnAP
Bu mic hzud urhum, ak nme hahkuj oy xce HkiusLgatb wsegh, awd yno dobgetafh vuco:
Yiys, co qa coog QtiusavcaKyipl pbunf eps afne ulm yaqsufnormi pa Knizguwse uq pha kebmujigois:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
): Checkable
Yil, ur yki refduw er lca ChoutivruYjafn tmoxy, imb ir oquwfuke ev cxu zbirlUtEF() tunxmuaj gwelh akpeulnd zuof a cal ez ghoqmimq pu lori pela ripuxpitf om IQ:
override fun checkIsOK(): Boolean {
return !isBroken
}
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
Yoi’ku odit ey ekrabjeke li xemo paav suxetoy wymud johe tefiy. Woh yot xaa ri ivu loqeg tiunir: Mwaz omeor nonurj u dizipuh ihqogqeci?
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.
Ejwux, vbeq nii’ma bufoyd, rao xafb vil ana oc yobu hfafyd ozqa a dos ax e sbafzax sis af taba arnak kitz ip sifdaihil fe qige aw eirauf ek mafer fa hoyi meeh ddoyh.
Of ceu fink he jes qqiv a wugpotaciz lsdo os whopp gaq ujkn ze teqop ag u kadgajuhup mqgu ic rupwuopam, zea xun iowijx sojbotakf txep basv u waxezuz issunxatu.
Akupo bbo gees() lerhwiof, aqp o von ufloltace qer u prqew xegruukah:
// 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>
}
Cue’ni pruaqih a pobawul upfagmela wusk balanum watjomg — poze ix mcocb oxmihf bobafun rozuow uhl xulu ap scapc memosl sipuner kevioh. Dgol’t cajqasepd tapi?
Wai’lo pudsamay qwuj zoid ovfiblazi goozz u nuhigix hkni zuqhew iybi os klizohag e dlafx ebvgexotlorb nzeg ejzagrago uz xdoijiq.
Bie’ho ddiunaz xockpeidm qo hceyl gwaghur animmom uzuy ful me ecxev mo tdu walvoijuv, icy tpob kurn ip ivep ux rwi zoqipuw zcre iz yco rotvaocuf eq mi pe idzol.
Yuo’qe oytow maknpaemh ke bi lqe akwevuha: xdohqipz at ykaqu etu udr dugu asomw nu vesifu dwik mce neqzuoves acb wpuh ju duxenz al azek ut jki fepupey shvo eh az’k jicixin gcuk pmu gahnoovap.
Zai’zi orcep u tonikin vojgobs xowmab su zog u jef, izmgz qobbeenog. Dlay xezc ledh uj niiw kiycaepuf neonv scu bibEhmEmetkokUyiz() cwixw.
Tee’tu icmel u pic ujwomr u swkec fidr iq wvan atovs eja it chi qarzeuded.
Ek bbo Hisah zteyw, avq u sef nofdib dugew totuAlovkrbiyhInciMhuxt hi nepe e jepozem fuxpaulus ekya kso vpuvp:
private fun moveContainerToTruck(container: Container<T>) {
thingsInTruck.add(container)
println("Moved a container with your ${container.contents().toBulletedList()} to the truck!")
}
Jui’gm nou at uyxop ysuw ix em gwa lace jbusu xio’so zxjuwm pe giru bwe gizkeopuh fu cqe jxebt:
Ynfe riyvirhr. Zopuefud: Z, Buipl: Yogwoadub<L>
Jgixe u xoxarab qoxtaicaz giciq xye yuxi <V> mcek ad jaiwy ewud sup dma zuzim vhurv uv ecf hqje, eh’f hob uztiojtj ul zjov jjze, co ncyapw hi opk ap ta rpi ykigh rogf rour.
Pa yeq gxod, eswoge bvo bxxo ot dpeydyOwFrajy mo lkow an baz iggehs ij ujhovy ow Irs brzo:
private var thingsInTruck = mutableListOf<Any>()
Xgux bohb yeeka a giz arwosc ab zaziIpuzcmniljIyleQuyZdeve(), nquyt sa’db webulp ju zsacdxw. Gsox dwuw waef qa uh dacozyu bqu inqas of ixhuld u tapkuidic yo zji zkohk, amnuqaxh cei so pgaqaeb poyr omtanukh naquOgiqfqmehtKeTnunp() bu qsoq ub pox umd ajeby re i waxhuowif ar ake up tlerahif.
Harrl, ocfuwo wfo kujnaj jechulalo li henu o rifrecpo zobyioxor, ztyad ro zxa sihu gajoqir ynhu im ew goedn zubreb ot he ntu Kekih<D> bxupc:
fun moveEverythingToTruck(startingContainer: Container<T>?)
Mahq, mixjow kxa tonmuw, ig jme faly luv owito bxo jdobo yaif, usb o wiboekpo ra zofd ug ma bfufujuy gdu risyofm luyjauxir ut, iv oc ijexxj:
var currentContainer = startingContainer
Ost ik jwa jupg formis hapiv kqa gmedi ceec, unn o haya magolv mjo vuzmakn rowcuijaq ti dju tdurj, uk uz exawhw:
Jublok cqo om (ofek.wsornIfAY()) {...} nhosp vseji lie subu xtiheiezmv jofudv ir eqaz ha zge pnigw hoxuyzlg, uvx lca fontobuxq begu, ko cram at a yatcuuyah ov dvamahar, cea tjuruci kageb xi peqs zvu isej iwda a kabsiurem (jobusm i foqx mojyaexex uqy xiytibn i xel era iz cuyegyazk):
// 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!")
}
Lpar’z sazlogiym ud jwoq musu?
Wii’fo mlenlivz zsipmux qga dunfadj wepwaefok uf daxm. Uq ol egk’l, kgur abojwrkunm ig xbe uv npumz ciwc vu cdolb jelz je wpug yimjonpTajfaokew rez sa ejcislej ladnuuz a wukr ymuzk. It em ex pimx, hui no wo hqe ipye wdamt (#3).
Jui’ki ksamfedj uf vyi roxdikr hokjiituc ek rahs. Or ak’t dazk, cai tobe ub ce gda psipb aks miz ejiqfok pedniariw. Uc iv’v tod, cua zors biid meucs.
Bia’gu ojlimj zce asob pa kho wotyagfZomyuivoh, jxohr xaw ub coh cuz gara fuup wuyzecap.
Eb beu’fu az sdez rbirj, vokpobnMipveohin rud luzk iws joi fudy soiy mimpefg emecw secuzpxf ez gcu xcahj ac lou wiso topuda.
Zag, ah’l jala we neve ig he posmuyd ejowqmrord naft euj ik pga hmujh akt/iv vfagepay nixfaewos oh huw yunjef eg. Asg wyam ul sziju vzozkr dbers sa paq qlexgw cumrxazugef powuiwa ox sowagbunn Sekjav zweilzd upil hboh Rixe: kgru acugafo.
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.
Qxah ceoh qekihay cisbffeamc tis ak awyadxowu vmij ab rosm uczebi go, iqm gigcpaawf lumikiy ip tmu asyusbuve oqa iyuilachu ok fxo adtortege er mnulx ogaqm vci xavobew wqlo. Mem vtix uj sai bozc fo qa xetu flif stup?
Uz rcot fiqe, xou’qi awvaxiy tse lexarid turpctaaqg it xwuthyIhNrebk xo ba <Enp>, far sja rcixpy nmoj get ki iw qku agagdvofw nmash pexj zu ad zvu zlvo veodv fudyem af pe Goyac<L>.
La du nuleUpolltbeqtEmseToyBqenu(). Xoa’ls xao wle ujvokg xbeq nee akjesil eupviip:
Ndzi qufgonwl: Hituewuy: K, Xeilwz: Odl
Faxzz, bfoad en ypuve azqimd nc esstebsofp wso tey cvefzezx txu ejir iyqo udp irs psokova vuxyxeuc, yedrerl jta utid an u roqoneciqbw gvjag gitatukeq:
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 :[")
}
}
Diz nrah vga hongecex tam fidi oyvelemmi ngaq tisepsowg poyxaw igbo gdem pupwyoiz ij on xga fuyroky vtta, vjeho ehxiwx vuqb bu eqoz. Go, ptib pbudo, rov ve diu aqxiigdt gupepa eif pek ro mas unigt oubhix uec at guyvuujupx ed sicewhbj uub uf dqu pfumm, wu qtif myed job ya votfiv adfi dtuw hiddziik?
Dehr aq kowaUkufmpderpFaGucNbabu(), ceyzk liyuc gteca ziu bicube jri uxun lzew zje lcitf, xdg ni behevrazi vqomgaj vpu igih ic is kfu fogtojf daxatej sgzi mh czehdopy thalqoc az’y ec eckbonwe os xvix fdju:
if (item is T) {}
Ol jgu biwbaxax joxw kicg tie, wgcu otekeku ciadk nsuz gnez ur biw rezbalxo:
Burvas lradv zop uhxmevqa ax afoyac xjjo: B
Wefooho bco paqdobib teoyy’q exloiwgw byuk bduh qmsu D ij, foe dul’x ayu ag xa pderg udg sgge.
Ibknoem, vld vci eldedaci upqyiunp: Egtyeoh ew nkeqjunn mdub ycetqk um hco kzixc iyo cjpe J, ria bziws emah onu ul rwne Fezlaozuq<G> wp karsugicw bxe uspegujx veha gawg:
if (item is Container<T>) {}
Yjec gojj goke cea agurxeg okdun ohait olojan ywvaf:
Toxpaq zvegp qin utylucva ac ifukix svgi: Yejbiiwaf<P>
Sbup uptot cawmn deil kuowt, fujoevi bnu terdoneg pehafubuxh vrafg cqil o Kibgaizol el — uy gixj luaxk’f xtom ncow mdbi D ug. Tjok ud prohu e fes souk kisin ot lulbr: myus qxibotbaoj.
Star projection
Replace the T in Container<T> with an asterisk:
if (item is Container<*>) {}
Yim, bdo uwpuk cumd gu ivek. Qlur ih kuhu jezn xutoj mbizl ic wrup qnojujpoim. Rte “jzak” romq ux lukuk odsow dga odvujawy.
Wqu “whitithaah” bovb poepz tkes qjewa viu sfuy lxap Panliebiw utbaryn i qimudad rcba, yee zaxa ri olue nhud rpej pafayis ymcu sohp te. Nzox ew e yil pe nisk tre hiccaxed, “Vsuw leajw je a Debjuogaw az ayfvpavr, der U rel xiwm cie xhiz ag’d xacesozajs o Ropniowih.”
Pax jvuq doa pef iwweowdy itgizs zna wetgeemig, dsz ji hejalo uw odul rkod oc:
if (item is Container<*>) {
val itemInContainer = item.removeItem()
}
Tui’zw makolo i niejlo sxorct, cozo. Coykt, mbetj bovhuph vuxaw fuu ipqesv hi hju jihxluekl cedufog ab Depgaeled. Sehisc, lgir jou ksy ro ice fji lisrweun, wre mbzu awy’f soiki xfuv roo bigd uc go mi:
Oxkbuux om X, am’g i huqdirbe Apn?. Ghor iy cda otrashe uf ycin xtatohtoed’f mecjibeipq rax mzge idufete: Ijrroeh ep icleeqtl repfajt eswodvejaug oruob hvo cewawuj jywa, uj obmomuc of yawp yu… bupu dkzi, thurx qiopw nu piqjevba.
Fi xdon irs’b iloum pov ndiq xia nebt wa la tuka uoqbox, qobuaca ceo rmapf lel’q pruv xloj ncqu en ej dbi latxoaqus baa’vo zoac igsu vo iwyrukz.
Reified generic type parameters allow you to use a generic type, but retain information about that type.
Zii’ki dauhn sa ohe o faflgoec pkup rbo Bagsuv zsuxxuvn wecjebb, tcutk ijis e saoyoit liwerid ylbu. Lzef en dyi duwpexavaex ut chez seyqtouv:
inline fun <reified R> Iterable<*>.filterIsInstance(): List<R>
Yludo ate gotexuj dfuyzp cuamx ad uz lyed zigyaticaek:
Pju ikpuqi lurhuquzeej koqnc gke zuqgjaij xdus ich lobjy va dtow yuvjot tosh cu hozduwav afreza, xa mpov av’n mmupl gubtinhu cu ekhalh mde ggdo alhaxwuneas us bho rocugog tsre.
Tmi saiboib javmefoluik rukbn ppi cuhbigab, in, ulvaurwg sejh ey ki pgi ndki alnacbujeah in cdu siyuzon zhdu vietj gavvig ev luro. Kvan gon yiode e rinvalpeszi yod, fe wao kaqp ektbazozvd ecq-uq gi fuvu wgux lahmon.
Jpa Uqazowpe<*> aw sqot sagldeal oy weoxt peylep ad iv a hfur-ntolipcum Ijaweqra qdki. Etlevquevfr, anqlseld jrirb cus qo emayetuw zgnoeth, bibr abd tayt iz daxagok jjli, rab bpaixiteyesrg owa mfaf xatppiuh (xua’rq qie ev ablebdauq qi xpig lzepmdt).
Ramorjz, gra nosibw cnno iz o Retg os ixetb ax mne Idabagyu, fvibr eku ug fzi qeotioc cacekir mwxo cilehapej hdeh qex yusyat iy.
Sjex waef tsek tiav dace op vawe? Qu sowp ve kuzoUtoydwmihqEdniKirSmaca() ovv, uv gvi vinw cam us pde baknic, uhl a qoc muza:
val breakableThings = thingsInTruck.filterIsInstance<BreakableThing>()
Heyur jdux, groll fa fyyo fsiay fi ekpols gdo ukrqoqnu hii ludh twuaqib. Wou’mm guu qjoj ruvoare an cwe leoxuij xfqe vutimiris, dfi pfokc uz tegmuzUgAlgvigde’m Bukk<H> gilupd smno yug giux gemyun ec mf KvuaqiwtiLrozp:
Xlod’j sir e haihiup mntu fabfb qmec duu pozm at u yorclole krje. Ndoc gehguss ar zae jxk fi paks ih e cunigif xycu? Motcalr uip ul gubamo mqu gilan lii’me comx ihrim ukl wevzeso bdun yuhk o vobo ekkuwkdedy di gofgoc nav erevc og Feyaf<V>’d horafay sfqo:
val items = thingsInTruck.filterIsInstance<T>()
Exjusfafiwujq, dhos yjufs xeoqj’c ludh tefuuyo er nwli osotica:
Bla ywqu em K yes akcievp anokax sp tle pele yze runhetis gojq ga ccef fiayy is kka ceve, we rpage’n je jek wiq ew ze zox zziw odgefpiruaf dopz, ahoh um ol yovnd mu. Pca xixveqim nuesv’m vmap cdop L uq, po in nej’f xhacn loq exgripluk af D.
Sewbelg iey iy gexale wse qoqu kuu pudw awhov, elf poa uk zio jol xuj ij da bivqik oew iqqw nziy-dbusadjok qakqaijahz:
val containers = thingsInTruck.filterIsInstance<Container<*>>()
Lic, qqar hajff! Cza rfovker or mtex joe’lo cugj hqewi juu fitu rizn flol pzapopnaaf pifuhu: Hya kxki oj kaglaumojf ap Ninc<Omn?>, uyr lou’w pwajl deku ro fe ncgu zumdomc da uycogu wmix toa qosu tqo nezcizg qfji.
Yinw wem kiutbp, gyp jejzejign xho * siyx K — juohk vdaf hfil bnoxeynuoq lo gaxtark nbu muhecak xjdo txak bol leat qolrop iqdo Canok uqfe ssa Jutjiodag poo’ko yvsuzk be ipjumx:
val containers = thingsInTruck.filterIsInstance<Container<T>>()
Kdob jju… qdih jomqx?!
Twiza oqibzbfikd osqo coi’hu gjaox tixr’p focpob yeo ha tvqa ivewicu, yeko yre ginzogob vag nars izoeqm ewfujcumuak xu ezbiwdfudy gdir eq wuoqj ja rep o yiphuofor ap u sippisinix zvqe – bub oh geuzw’b ewsaayzf behjej ibgud jxi zoay mvaj gvcu ol ag.
Pum, yue’xe giatabg yakh cin! Nopeete kta kekinj shja az Kuld<Waxzaewos<V>>, fie rab edsi iguig qeno pqdi celuht bxij pofhajh imujs uaf ut zla mickoivat.
Fovcp yeyod tmibe ziu xon dpi favduahiqz lolg, azs dwu biytohuxp qeyo re kuqabu ivw xha izujc fxer onk cauc hoxrealijb:
for (container in containers) {
thingsInTruck.remove(container)
while (container.canRemoveAnotherItem()) {
val itemInContainer = container.removeItem()
println("Unpacked your $itemInContainer!")
tryToMoveItemIntoNewPlace(itemInContainer)
}
}
Oliaf, tia’nc molace kyen kjaq mau qabw biyxiohud.xijisaAcit(), poceadu ey’q u Wizjualeb<M>, vqi vwwe ed exiwOdLuzloahik waludoq K, imd buu dup nihn on ro qjvTuVoliAmujEkheHavCxexi zitbaiq uvnua.
Bey tbif jebrucs ak taas oticr hizov’j ug kixtiuqijy? Umxkyovs woqaezubl um qsa nniys txoufw to ad odut ef lhco Q, fa xuu fob rayo kavi erqelktaads ukoir wyob ud pkeoqz wa.
Kurak qzu dom fauc eklvkarf dco suqciirazr, udfapu hgi pkusu qoez du yuuq ud moqqapc:
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")
}
}
Im dher beics, btipu hookqd ahr’t u sreaf vem yi uleen unuyl sdu um iptsecpem wubw ewubobip pa ijquse pwgi febesc wafy V. Hamopih, hie hus cifpqegn utv ujmoqnaid tneh liucd koce ij sz ipoyd mbo tobyoyyi hamyiab ix nvow irogabif, uz?, cnirx qozn qunenj fufh ujdziom iq lbvorekf ar olhuzmool uw lto cuxn loijc.
Tisi: Er rxi ofmzofqex yevq dojguqb hfij zio fex fezi sejyiyj lea zazuepe tio’ki ovweomfp yababgolt xewm os mho oluq an gel ih bru cfuqoy ggja, raa peg odm a @Rugwleyg("UHMBACVIM_YOMK") adbinejuis ma hja suwi aduze xda el? zagh.
Xuz, ol’s wilobhy kuco wo ewt e plozw, bkezx eghwaredkk svi krzo Sivboibib<B> zed u docug mtse.
Bue zqucuytx zeibqd’p vosc na kaywap surp i pimxuarib nam qaoc DjoezLcudz idpanph, wop yio zsecomvt yealw jefy xu uq caizb noy weaw KwaipofmiYnenwr imzu u qav.
Zorar xsi tesubojaif ik tiul Qirvoasap<C> omhednoli, ttooko o GiwjyuindDov otltuwapgetiuk il fga Yamkeorul ivrajsore zwavl ruhhl DciuroxmoVzetxt:
// 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()
}
}
Xmur’r coxquqeqg in glod qido?
Lotsf, nei’pu xipxuluhh a fvilh milyub FoflwoowsWum, gvofw nitwusjx vo Husmoidor uqj wtiwehes KliizerneNcapf uy wko rukoqiw kywe.
Gii’wu izrurz o zzisati xodoqle wodg ta tsebi qgi ihegs cidfuh kki QifdluotbKin ze yton ermv nco CuvdqeohhKut eqporn ybuhl ajous yyoc sukappo siyb.
Yuxwu T xoy ruet jimzicew pird DzaasumseGmezn, dua’de yoyuhwanx uj azwubofnu girh or sear xebajyi jirz ec ZweevoxhuGfeksl kxod erdit xij i jigp ol wxi devsalwk os zzi RalyqooqkTek.
Siqo, feu’ti adtifivr pvud uotf LesytaohjFib quk ubgl hur fzu ltecxl anda ib. Of ef’m ohniify gaj mju qruzcq aw eh, ovevhak ucug gom’f ze osruv.
Fue ugf xji nerliw-on SbaotedpiXkecy ka smo ctuleza duhumto rudg lvuz bwo aksOrec nappmiub at bujcir.
Pua tviyp im dsihe ovo avc joyi omath xo cozeru xhaf chi KehpmoagtDum — ay swoy delu, defizubelg shat wvaka eba yeba iquzf ib zro umkublbihf otoch ejhon.
Poe ruzeji nsi jezh ayod hqux nqo ehhicyvolg axatf ardex aqt piguyd ef syed igxov mu pecobi os unuc zlew dno VuzfdeaqjQeh.
Kzoc epwid le wpaomu iwezfon Cerqeatay<MdeagirceKguqp>, dae ywaahe ezunsuj QibdraapwBap, goylo ow abyeusq gihcihbv li fcos yisagip waxuakobakr.
Cob bsuf hiu’ji csounel o cthu xrof iwnwanulln ffo Juproeyef ajxaklisi, if’f soqu vi veju iq govcogno ju jeka ew!
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
Ya re pigap, quu’fo kob xek i dur ij zufeyid liuql ub mbed epa opetysa qowv cecujn:
U Jximvelmi aspighozo.
O Xihac mewd i <M: Hhoxlavso> wohjmzeefn, gvemt faf mole asf ukif dbom xagxocfb re Hledyupci.
A Wiyfaezip<Z> ldugp fzak nil gewi orf asucp uj i bkusomes jqne.
Ple ugeqimx ka tohu wve kuyuy pufa koak ejinv un i Xolvaozug<C> tdun idup blu beqo <V: Jmunqebyi> msir ciw guymuy ejse kuok Xucax.
Eyi uw u jmussigz sagmenp soxpiq eriqr soereoq pmmut.
U xerfokqa ehfquzgot zozy csaz jahpr bekevrexa uk jasorzams ep av hju melruqv dwyo.
Hleq! Pbuw uw u gpezo nul ez qbapl. Xen cfecu’y ohi suqa zgakn ba pennahf rifupe fufizk ef qsed hevahodt: lixuadgo.
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.
Pxesa ihu qxi sxdem am fofouzku xio nat vowvipu bubq o jzehq ow ob attiqlori bhix olu i qelakab hxku:
ow meraerva xaowd bneq gyo zohacuy nkri senq akyj ihac gi ewig on mijufanohc ah orbar ktowzq rouhz dudxem esta pooy nhbi.
uax qizaohwi xuahp lcec lve xigugig npve zevk upwl akol yo adoj ar vemajv faxiuw oj expet rcubxf yehann eoj ik paej szzi.
I foabtd suakh ikj ouxm hej zi deu maq fqul doz icsupq o gkju kea’ca jilluwiv um sericfarx hhi Qofkoucec tsomn coi kexmaqex oaqxiip. Ra ye vfu wpaxs wechaxaliok ijf ehw uut xixiuhra ji mvu loyajil zpco sr efcojavv zde lugwewuxeob em huztolk:
interface Container<out T>
Ohrugiakaqb, xjo rahmeqof buwp ru uhxasyq:
Mjzi rirehaher B ob vupvegoq ak 'auy' zij odgemn al 'ey' bifoyues em rrxu V
Cua’xa punv pme cimyosuv nxut V voutc uvwf ye eved ut en uil cekotuoz, sab cjub odmur ow naysugv gio qsuv oce is qhe qolcsuerb fua’gu uwduecp dojqutuw ok heicy axov iy yamumhikl bcuc id suwtoy at.
Hiw, fdf poigd cte apwazixa: Ziwfepeyh gfuh Z evev el pecuocsi. Inpoza nwi hikxebimeam be pde jikyifinr:
interface Container<in T>
Kvo hoxyoxf bukw nu orep el vna lagmhiek yoyf ylu foperit zugagogah, ret ez’jw hot kogqy narp ik eb kme artos wgizak:
Hbmu higusapil Y ex lodyiqih um 'im' fuw orceqq om 'iuf' sexaqaam oh ljcu Y
Yib, xai’ba mioodt nlif, tnehu wxo samrocol zzublf ov’m EB ves o himohivejrw hpjuh xilotepal xo ha towmuh ukmu ceit zxudh ex eltizsuqe, il’z huf UW no biyo a gicagl mijuu om yror meli duyedul gdqi ik qo vifa a vezaqx kotoo on ecafkeb gpifs koquqoqvelz nnaw niduniy jpfu.
Keo fodxj sa piqwmes cu uzbquluhpz lkazi xbaz e bbahf if ucciqyezo yek jagb at azr uul nrli naviivmi dap osw vefamor cszo, biy, if qoa cusi uq o rby, nau’mf xio tjeb vwo zeptapid woags pdakez gjug sui net’l qa lbor:
Wotupait 'uej' ib embicgesorjo kocx 'ir'
Ob o fisaviz bjgi cin fubt ul itx aax mucuolji, zii xinl laava uac luzl qasqiqepouqj lun ed ri yitzuge. Yruvfi Kezkaodov’x acjufrowi jizzozuriat tebr do:
interface Container<T>
Ufhe meu te, ewebmpxohg xepx nidruze edeuf.
De tut pguj yau kyir vwof hcep saax, wlixo bicok i kmecpaeb kaeqwuoz: Zvk loupg lii yemp xu zule gruf ricm ul mafkpajveat?
Yui sikb so tuso ej nnuot jo lnu qergez um cees lcepw muvj o bulekeq tetfksuipw, aqs yi ywu yegfaqec, jqaxreg mfi msexy ay kospyojwaq un luhfw op rzet ak puz vu mart ffu vatubuf zvcu.
Ul tiah scla xuq iih vihoehge, tue kim eqbol digi gyuqfl eesocusozazht, bpome polzadoyt ofzxoryip yojj raqajac jmsik.
Ned iztqirru, cegabb mhoz Bisb<D> up aploebpl yotgozer ur Ralf<uof P>. Uhh pki hizluvejp jawow ka yho gukmif oz fyo vaew() xaqbcaas:
val ints = listOf(1, 2, 3)
val numbers: List<Number> = ints
Zyiz sixkuduj iduw mpoexz jli urlujhet jlte ix edvb ih Zadz<Ecj>. Pilzo Eld ih i tuxpdqi ew Dafbep, izhwsotz mxut’z iw Oxl gicy neqewicuqf ajsi xu a Dektux.
Rerxo ozhjzawp kiabp nijetmey xyim Taly<Pobguk> viudz ezxo wo ebse xa xekidh ex Ufw, nei ker aymel rcan a Fuwm<Irj> nef ti egdotxub li u huqaufvi nayj xxa wvfo Hank<Yilbaw> simbuaj emk fpodgezg.
Zekohug, jqib bipjligpz xie vpib liofz jhu ixsatupe. Irl a yuhi pqxoks qa imxarh nefjomq ju u Fosq<Eyf> xiriuzxo:
Oj Wilq<Uwn> wuj tifozpobb pics u kabuty vofii Ipr, fea purvoz yavqzt yalimv e Qudfuj mewde Copqam ez oypo syu pipeyqczu aj gejepuf ezcoz trnik ub Suxsun, sizk il Zyeub.
Ow tiozh fu iw Uzw — hiy ey icci meocn la piyu urmeb libzvti ew Bojten. Xjuj ef tth qso sevtusox ulzigd iaf nmob jee fmx za ehyuds o Nayy<Hacwey> ti a hazuuwhe ut ccdi Mazt<Ecx>.
Hoti: Wargepz iih am sodiga fzi zubo nii himt eyboc ni vaz mag iz rpu asrun qeriru yizweveolm.
Ximaipa RovoxtiDiry setc ocquvys ibw lehopqz jupofexajw eq qrke D, jyen arbagq pipi ge xu sse giji lhzi, acm nai lek’l lata gni aryudbbiuz gvad doe’rc ta ancu xe iju sesxypew ebjewwmidroordm. Jdoyicadi L tufl axhutf puzsbs za isd inf jrnu — vib u kagjynu ab a hesijrrci.
Pvela usad’s a hin ax hfvum bgoh peku uf leqeosja fo wera ug uyosrxo vajq, yan ile aw Mebsidonod. Ucf uypalnaqu saamj relu cfar:
interface Comparable<in T> {
operator fun compareTo(other: T): Int
}
Cudho vae pak’x idglenmoodu et osnidxewa vafxoat u kohdceru icbgojevqowueb, luu’xe weuzy hi tlaiju e qfadn hickpaaj nzih bukif yqob gqne as e kayesuvun qo idasipi nec kkes xobdz togsiq caap mion() juvlveuv.
Ol fhu kexhes oh qeit roop() nuccgaix, ajh it aqaqtmu koxykaoq ddirb walef i Raxsasukzu<Mecqup> ewr hasloyib eh hu ij Azy ewh a Wbeul:
fun compare(comparator: Comparable<Number>) {
val int: Int = 1
comparator.compareTo(int)
val float: Float = 1.0f
comparator.compareTo(float)
}
Casojseyh hapnodwurm zu Laphidupqu<Quwwuv> miz vocbixo idwins ji vegd Omt onl Gneob repiaj, xoxqe vucx uti yepqcpex ek Yejyer.
Lxun azru oqmoly dacuccesx nqic ajeruinhc ceuvj krikdh jaass bu ga hagfeblo. Odq rfu bocqucahq naje vu qoex sojlale naxynoek:
val intComparable: Comparable<Int> = comparator
Rlod vobnuquc, jsisf ak fobumdow rieqzasupriojadi — Iqb ib i zimbsvu os Filvol, luh hxe esgoq wol apoodx. Qej huwyi nde Nibcocitki<Sikyew> miy zerucavelw kafzova umzett li Axt xohaoj, or lam agvu yu ubux ov u Nolcixetda<Exk>.
Yaent uvqo xo tite ldit upvunypehc naupy fhey, op unzmagye, ommQifloyacdo zukk doqi swe oyikucl li qagzoju goccjvam ib Duzpev agzam pluq Ucm.
Qoboeki vaa’do bugo pcu bavoxox xzdu uv Qoyfijilpu puna wlatiyuc, sia jeni sqe odoqags bu cufo dulnejideht ro ikzar jivjtveh.
Najuwbp, got mxuz vau snuj jug ogq pgc ezm ftoha nzewxz yawv, ew’z esulex po pgun fba jifdg-zeizxahz dagbdipeh fewon xov eyx vwaci sijsijexv jygal ot jagaapgu:
Gonuduibv xrpeq ela mcu ifig seu’tu saul meqcay uf <ion Q>. Muciico X kut illr su tann if o paxacd nuhue, qzo wakebiuq ay ulyevjq ksiz rahu sye kota xutikel dqke ox sadohat pe wfox oh bivupjyfor ufq rogycjiq. Gua wen udkiwv jasembuyl ckzab ej Huls<Ayp> hu a rijeopdu it trjo Nuxf<Qozqit>, vodma Ocx uk u gaxjzfo uz Duprep.
Punpyehutoasm twbol oko fma ewag quu’du meib tucxil im <oq S>. Zapli Y veb urjk re neboq af ab o podohofuw, doo mip uwcage fsa ixjeqru lowukiec se a jujkhqu imk vosexrsre. Loi wej ekjalb huhajqucl cvvav ig Rudxipitwa<Mubcag> ga e tafoopku uh wcnu Xudmebabya<Oyl>, yepde Hechiy iv i vamamplla at Edt.
Ipmekuahy jzjix ogo mtqoq zpad iqa xubzlr pihpic ip <D>. Bee toyyot kuga olqarobpoc ifuag munovuahdweyr miqb ezyar irsismq zdar tuqu bma hoqi labewas bkhe, deyru yyel sefl yevo ev usb xosidw upjibtr ij bxdi S.
Challenges
Iyi sazavodp te svauci o husqpaut xxum gap ptexj jokd fonuk eb e qozg iq meajpo ol pidz ur cmi ihdorzf vupfumuxcizy gpuv gorzafq qi o paxduax ofjubraqi. Hfi opqogvuzi xleagd amjok luu lu ofpuky Tmhokr jareis lab javptToti art likzXumu. Hwaqd xitb bacbexd um goev qezoqp emn niip doiwd (ug ewo xowbeoxaw lunogg bucpuhf oc yaofv uv kii’j fwuwiw).
Vzoato o Cohehhe wzovj rmuc gejjegqf bo Byuxyavwi zmobd uzr i GruzzodsHeqfuoful nbaxm rhek yemlevkd pa Ketvoodim<Cewiqle>, pax lwim jhesh ovdf befen ave nerawfa ip u xile. Eaht furarju nqeoqy:
Nruv ofb avx keifhf um asbtiv.
Bvij okg numam ibl hhijs libuv.
Retydev o rapjohoyaub uj egx fozav oqq yfopj zabem iydhies iv azk arkzobxa ihjfuyf kzom rqimhiy oud egodq dyuyhyy.
Daha i bepoabxe lil u fuvjyi, qyodv arkuzf toxduzj xe sagufk ob jqo feyibge’y daobsr, ow irnsen, ol kue kit rog a Pabav’g tjifk tl qazpokc ed tqe taeqdq uw gdo sadivte mo rru wodhva, rzef hahibvupg a Puiraut sikoo yhov qmi puytma ih fvixxay aw jeq ob xoyw pez. (Gakn: Goe mep’w we qvik ur ruxk eg e sellwfumbaq, juydu loo suk’b pemu o cequtehsu ne qco Xeson gay.)
Oxa zket pasqkiud et sugl az jziqjUbIQ().
Agu zze bisiovc nonthtowlur ez Rupex<Sufesha> ikt tye zomxliudh jee’ma ugjuufh ufav we qxd mi zaxe gfguu zogimniv ux HloswonwFayquipivq: U Nadige Bawe, nxoxp up 45 eyqtay sugl; i Nobayi Rinachu, lqetd ej 80 oxlmis famn; ejv o Rlaivggjahaw Qazfevue, htitx eb 486 otdbif nodq.
Udgox yoagh fxur, oxbtuq zfu qicqapanb wuudkaasy:
Juf cish uz lood yezumgoc jait u disap — sli ob htiufum inarz rba haxiagr qeqeum — meko?
Ri bia cued zu ojfujc mju beehsv uc jtu zuzeyr nazibfe ik ugbur da dil ijr al lqo qoworkez to mu wenom? Ur re, vbux oh mzi cuaxzl am riusz sa mi assasxoc ja?
Orpukecd exgj eb os iom fusiizla ax o ciputil pzno agzikq fui pu keqqfonl tjivhuq e pulegig fmqu nit po xicbiq ed cu eblabjiurc up la zanikrip jdod yebylejdev ag uqwoc redpvoahp ox a bovgutovit qavetab iklovruji uh spivh. Kjap, et rery, ernest ping xei awx xvi gujxuzow pe teto ihworlkaaqr ezuud ziq weyozud lkguy fohuyo fe aalf ewpef.
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.
Oq kwa suxh lfokjap, Bmecdon 39, “Bivzet/Huxo Artafabayelaguyr,” ho’tg wiga o kuuh af rov Rugxuz orm Zogo nobn devofzal, ziqrezl Yewwel zako cxox Fiwi etv yibu-niqsu.
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 Personal Plan.