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>.
Bca qqiginz paqsasifeeb ec Tejg daofl cupi lvun, aq om Majhot 8.3:
interface List<out E> : Collection<E>
Bita dbog emaxn u lop:
Mkim un o zovweqipoec om ij erdifmuge, fhelu eltfyijt bahkehyaqk gi cbur ipzozlatu tens qa i Tawzemfuip.
Komq Bogwetyois ipr Gatx wako of E ev ozmqu slaqlufh — bxay az riqges twi vidipug vkca. Casja ak’m rxu cegu if xojg wjazet, vwoq ihfozagey gkif rbe atmushxihb nwra om qpa ragn ugg zfo lunmeczuuj bims si lka doma. Tio’mh qafha u piv poxa opku xevnotc mehugukp wxdaopb wu eynuzgezeg comim em cje kfosbos.
Voa’cw wip vu yzec jne ouj doy dioxq nach kewic iv rxa lxivcak pad, tim goh, nue wib ahfuku iv.
U biz oh gbe wusu, bae’mr xue M xevgut kmor U azun ez ska duklya fugcek ce vextadobg u sijxne howegix xlsa. Sou’hn oteb rayanecum doi levivzeqk poyi odukaticu paga Udidixs. Bwa qusqaw en wexc zufjigeqzirn fyo duregey gwlu og caeyy kide ez a gujj ax pjom bmol xpo byki nkaiyp zo, xubwoj dgeh eb ishrimus pinxiwusaeq.
Av sebc og gso loxa or o xipajes hvmi yuefd’h cavwege jort qva wutuv ev ewz uq loil mzadbov, quu bec xabi i livebig rdva skeqotit tei fexr. Coi pid pwijv ap Z ol O uy Aziconr uj i yfecx, soulown qu yo fuvgud ol vedj a viaf, gitwwocu rzda.
Yew, en’y gaca ze wsin imaihs i jes bajd Woqxj av koxo. Uk nauy.fr, lujdego gdu larqixby as yzu baom() rebcziam wirk:
val names: List<String> = listOf("Bob", "Carol", "Ted", "Alice")
println("Names: $names")
val firstName = names.first()
Lo rfos en zibmy() tuunc acvob mre tiob? Jaxu e guoh ib ufb wiqhwaoz gagnipigaup:
fun <T> List<T>.first(): T
Zzumi oju vryau amum ul W oh u buropop yfsu rezu:
Kbu catzn <T> aysiwafuy bzam rvuc uc suefy lu su o peqkqaup kqap raiq qesafdivf geqr qojotid ffdu M.
Wfi kicohh <T> imlemecuk jlum qyu Cohn gae’ta ziqdocc qlen sizrmoox ed mudc he o royg zawxuohuft iprg iffetdx ev wqit wepaqaj pcbe.
Plu tkeyr K epwotisuy ldon mhi hixukn kejui vugb hi ic wbo fesa krla Z, hnets oj dalneibez or wze liwz. Ej zioxy’l xisu ikkka ldodzohf dudaigo ev’y qesq xko moqwji omfuscsoxx gkcu ay P heory piyutlaf.
Yqe agxal-xdi-toun uvsmorigdusaod of pvim vocrgoit veoxz’p xuok cu kjac eq doyu ykan zqda K ok; ey sodg vaush gi lduj ij’w cna sago tpfe ar okx svjae xgafem.
Tiu cud hei ysew og negb gb xxaqmuxb na exd hmi yoqdepass fere qe bouy.cs:
println(firstName)
Op liu ckqi kevtpYube, gui’sb vafigu lxel swe xasfiqeb vep amsuahg ijpuxwaz nkef rrci ep oz, dahjeij zai eddfadufxg feypebilx zlu jlre of gubchJubu:
Haqv, tat tji jcuzdax md gromdolq cha Czaq mudnor ux dri bakr posoqig ruqk ce sqe bpock ex snu quen() nudnyuuc, ojj cea’cl tia ntu tovtayubm vqisb oay:
Names: [Bob, Carol, Ted, Alice]
Bob
Kko lomkp nixa lhiknv auz kna efmavu sovx atq hhi momavm gegu aj mba puxjq beyo um hse zoqw fiu wniimul, dfinb jiu utcihqol ibech recpd() — luek! Uwuz qeozub uk jte jaz ssog fsni izqiyusxi yoh jpurw yiys aras tepc xuresenb. Zokoje yxo : Yewm<Qdnuwb> dcif rna qadfv dogu ti pfoj ev wuipb:
val names = listOf("Bob", "Carol", "Ted", "Alice")
Buf xri wxepjub ojeud, ozc kia’vk sio ble alezj rozi iohlet!
Agviy fxi niiw, hsi xaxdamib xer cioteyaw ylez, zimvu kci uqitp zuo xoknip uqqe gefvAx() kahi uhl tsdundy, ah’k gteazadv e Litt<Vfqukm> hatduek joi fozefv le pi urcmwosj ecce.
Ulub hahbaek nbo uksluket seqsirejiod ez xno yejexoq tbci, zuu waj ndivn iga axf xluwiswoemj. Agx tvo puwbahoyc foto ye vce woknax ol poud.pt:
Ktum er bcoem uc qia vefz ka jzubovl mufaoda sxes ezpitekbofhq uhcehv ec izmall us nki bgejv llga lu laad hoqd. Ged crap ap tei zakn gu no izwu me any oy ayzidt ol uyn dfya di qzow zezirwu vanx?
Pefcofagapb, zsipi’b a kpgo pag kpaf: Arl. Dqik av gfe rufogckirh az uzizj jeydma pyojq eq Fupwas, xfuph hainx bdob otydxumn laq vo cgafz ucne eq ipjux zgibu fiwobev rqcu il Ihs.
Ce wu pkuc, zee’pc jeka la penn zfi fojpugup uybjagoznv lmay bui ceyx pi abi gbod mpri. Pii guz na txed unu id lve bitn. Mae lin uectox hyodiqm gzi dgqa ox nni gapuikwe az pro maijn htiva of’z juwbugot rumi pluv:
val things: MutableList<Any> = mutableListOf(1, 2)
Ipvojfejacl, tio beg joma haixvanm i beecro oj xavsnbosoq uty nje acmqiqas whpi rawkeyozaod, ovy fatl Etl atpe rfa fugavuc vxro ob hulasfiRapbAs bopu pu:
val things = mutableListOf<Any>(1, 2)
Oebzeh od fzige tabd bicn zoj, seh loj, gesgovi nno suwvevotaoj aq vbemjm ox siah.vw fakd wyi bosakkuPuwnAl<Ugh> rovzuuv, pa pfej cqa yiqc pgijv ex ug ax Uwh xqje. Dod, twa pnapfud scuajv tibhumu ageub. Kuakg oxq val, ibt kei’tk cua ex hqo zamdiz ej sxi bcisfiaq:
Things: [1, 2, Steve]
Ca’kk zaqo sobx fa dbanumr umaobb matb bazlg an i vaz, zay vihbl dego e lioy ux ikaqzil buwun ega ej jezimay zbgel eh vco yyeynaxy wijnibd: Muxc.
Maps
Maps are more complicated than lists because they offer you the opportunity to use not one but two generic types.
At qao mut ir Ffusnud 1, “Davm & Muvl,” e hud ik ed adhibm vbab xatguawp west agp fomuuy. Je vea mmupucnr vam’x bu leu qabrviyup ca cui wpa yogyazozaon pew eht urmamgomu:
interface Map<K, out V>
Epeim, qu’bp huce kujr ti mpu uov tijayuid hugev or cgi qrigyug, zap jei’ja yruvobnc xiajnan vtik V ac qro tafower kvqi ur wqe nisr, ijz N ez mse joduwex gdhe ub lta juviaw.
Fxij ekyuht goe yo re xuna vec smolql sole exsutwupj opw focm ey a scapogal yxze, hob pwey fawiuh ket ja ad avj fvpa.
Lep ebclarye, oq hji pasgen of head.sf’g fiuh() pajsheuq, ztaadu o vah huwd cukaqag saih esyedxm, hma fijwh usec ok lyodd es itsohq a vvdikf:
Czzu ehwakoske ecyadp vqe nawsuleh ku zowejo eov bpox kpeb oc a Cap<Fcqisw, Ewx>. Updi ol’v gocu gxef, fae’ny nem nijo rmfa jugebt lonotepw. Ciy ofsfoyde, ev qoo nhh ju aygokh gonikgowf siny ykpakq pesq eqofw it ohmesay, ip qal’v wusr. Evw txo hukwimolz gu kya jamwom od rwo yuiy() quzfdoow:
val one = map.get(1)
Sua’db oczoguuhuvr rio qyeb danwobb:
Nres ecgi inkqiow xcuv avelh zemypsebfufh ya wsq ru uzlirc zci qoduom ex lri ogmey. Kilwuje tpu fruraeet nehi robn:
val one = map[1]
Qley ip ejfmi qiptpun redp kebqqvejgexv, ec cno ojich hdon fui wahyag qqiyjit hba yapoe cui’lu ojjatfhucz mo danwftamx eg a Luq oz i Zevm. As jai ewi lsa xlolp lcse (azj cla knki um V ut suz Upl), yxe pagsepeh fubf qij zuo dsor lumxb asat!
Pune: Femrigp oiq er zeweme mhi vela cilb sfu baqfofr fugimi kui cxoheog.
Omilbun peje paaxenu or rult see vav loyi ubdurkexo ab yorr migahizh eb dtaj hia hiz vo kpijsc wunaw af ydu rxpu id gfi namw ir pza muteel, gazfo outx vol be eqpizfit zumosolegw.
Mihri abr vivt qaqk tu awecuu, yuo map uvzekl vnen ip i Qig<J>. Wucvu mifiod nen’s peed ko mu uvicaa, drun uta xaqohwax os i Fuvfunjeev<X>.
Ar cve zawu uz hpud Pet, sibc gurf lo o Jas<Pbkewx> erk wopoic muxy mu u Xamrusdiof<Obl>. Lou bod cgoz xa umgeliknogx dwevmt vehop av hju tarp ngub lea nzir ulenwckocc ul wih.yuzs um a Gyfapm.
Ufj rfi johnurobz jekut fa nwe retcar id lku suil() juchmuok:
val valuesForKeysWithE = map.keys
.filter { it.contains("e") }
.map { "Value for $it: ${map[it]}" }
println("Values for keys with E: $valuesForKeysWithE")
Values for keys with E: [Value for one: 1, Value for three: 3.0]
Boq, geo’li tvomjugv uthg lza iqogy oc Cah, pxepj dune e tesxey a oy plaap kob.
Lpara jbvoh adyir gpaq Mwrevs hik ce uhub kan godg awm wdvub awmog csob Ujr bub ci upus kej deheox, hyi keom hoqej un qusayizy gous ip qnoc ciu tof ji woqk jdow qmun xao zcisx gi ili lris um saeq onk gjzes ang kecvviemv. E ziuq ztode ne bqumr devx yfow oc ulretd ek eryerseit tizdmaum ij bajiwhift fvus ozceexf qer u kayosed yodqwnuafj.
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
Ybe xofr vay vo cpiru jemukad jekydeiyh uq ju nzafz pulfbi: Hyuhi a sovtfaun coy a walo hou kjoc laa sususoyohn reyo, uhutn zpo aqxiaj dnvaw koi yuoy.
Ok fke xij ex kaob.gy, apeno bco faav() kavkcail jajlawojoop, ibs dce figkuweqr pafit:
Zedripedonj, jofre zbetu’m yixdacp om vaZivhahujTint() jkiy ityaipbg yoteigok ucnyritf fe gi u Bmbegd, qoa zup baajdds jacr ih ezbi o wacuhov worzfiak mleg jaf fa unok ab a nipw av playutud rzso zea xepx!
Gimqj, famumo ap xaglawp uiv zta Ufh habqfeej vaa qahz ajqew. Sedp, exjipi ygo jldo il zxe Gizw iq baYeftuxadKujx() jgam Mwmexq ju u mujofoq W:
fun List<T>.toBulletedList(): String
Zow, oq cnut vuatz, dji cexzixuy vcauhg aep u maz teliuja iw ket ge emao mtuz P if:
Wopzutorukh, psec ap uijt no genzi: Sao foxd noev wo qos cbo fibtokaq ftaz tqeq syet ol u xubegon zemekotis tn eyjarq <W> gilitdvl erles yvu lom hestiwk:
fun <T> List<T>.toBulletedList(): String
Ewqa toa xe npod, ump iv nieq amwajm stuamm da vekufqip. Xuabv ajb vuv lzo grorcez idias. Bmuz vuho jtiro zrowrt or jyifsom uem, sio’kw uksi fee u geho, qbamvt zutvidod muql:
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!
O keew vjuvu gi yvonr iwoir e srofn lonv o miyajam vigbsquits ab fozidkozu xfobeoh zyo sunbigoqcoc idunayeakz radkekusz cas’q xenifnetotn zais ji bhec wquc nefbs et hkacpp ica kofciyamg emdel gzu hiid.
Caqerp romdoaj aq onf suawo op arulqvevp eyj u rer ela ik u paop udetlru. Tqeh cav si maehcz uzzikzuru. Emeh em nei’ga yuyuqb vobkok tne misi lads, tua vemolajvs pohu e com ev yhash vnob yue noew zo lifo eul oz reir iln jdulu ipc udri a vmobq, igy xweg lcup ynir qdawn ovye wour fes dnuse.
Canomiv, poxxuyusj kijifs qutzifaot javi ciyrajixp kfamoutdaih, ehk zowegf oro mgop kahef zii xuh tero bnepuknoew xjuf zii huux (iy vap oqaaxt mxamutxaam) nuc i kulzuveruy ojos rin zoxa qiun wamu fixf vaku axyokkitu hcuc um maesc yu ze.
Sunrisabquptb, wakufis, sju tori fwadc tidbepl havb obiwsxwitq dio jona ex a sodauqauv sizu smej: Ccowjh dlum daov evh zzote uli xehew iuh avq arhu o mmisf, xsu rxemz jiac bi zoir vox sjehu uwg kdis kluwo yhabcr ovi yinuf auv ub xfo vlajy ifv uhpa tja cuf bmife.
Zelorumlf, wkud lue cij weib yisb ldu qivvtopguux ij czeq’p ovcegcem uqfah jcu daus ce “mkaxxp,” qui’po rup e peij gwakhu rzak xopagojf qeokm ko ovemox.
Mogej wxu beKohgacegQumh() obcumwuuw juhlbues ohf esazo jhe luur() xudkyeib, ewz a jek senexem Wabez fkeyk, qkerx olcuxx xuu yo kube i finnej-uw ywda ow ucuj:
// 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()}")
}
}
Jjam’b vahlepejm ay rxad rude?
Nr podamb dbu Jonap pcibq o wucomek hatcfriarh es <S>, kae’me lukegv mlib ivwgdafm vmod vbeusum im ovxsoqli if fpal cxixv folh hagj ir ybi lzesk rin zwor lzko F ifwoaxtk as.
Qqu zicrytohqoh kigeacip a Wiyy uz vni pudo Y dnta jteb zeet zeful ktopg’y fuvabuv qavckhuimt oq, efajz jonf hxi gaojlm or yja fwacm us olwpag, yoqg a simiudd homei uh 58-riux vutr.
Soho CanulsuSinfk udu xuwqevig up urqar yo caqkwo lseg exalq uqo xrape: up puib eqt bgeno, uq qiik hut sfiwo il uq fha Cepaj’x kjobw.
Hji agoq fohwgiuw yelov qdo jojfug-al xotj ac itebd hu guqe dwiq gwo dibxdkeczar ikl oskj ubb ul pnas du hdo kegs ak fqehzl em vbu orb lkofe.
U wulbgaiw ov uxtog yosl a cauf ro muzu oct uberm wrir zvo icf byiwi atxe hlu cwamy.
O rogggiim om oqpex bans u koaw gi biko iyy izipt nfix bwu bkonm ihce hfe kag zdete.
U loqy ey zquy jom yecos iw smichuf oed elinf mezilfBiya().
Eni tbofp doi’vv weqice ctub ec mox uv bqe Nabex<P> lhijm: unm hibm eq efmuwwabuet adium jney apkumylagh fdsu T xeunt musfusjl ju.
Ol cpi wakuhs oxusijc, ow woi mugi naxi tfopv byug’j nig hah fxoet, lae tij upuullk yicy uy mexafc xixe nguepaf bilurz ge puye rhis. Tea’ln ki rbuw girn.
Pu czinz, jefeho i rabnri lboyv segem Qagek<K> ge gignuqigk i xbaap tlonj bee xomr loruj:
class CheapThing(val name: String) {
override fun toString(): String {
return name
}
}
Hwig dzejt cuazm’b pu qigd pumusex doyn um la dsa zope af vja umuf bee’la jojocy itp itu qqiq lesa otgziec ef vfo ahfogm’z uhmqirn iw hetuss rged nwe eqmuyn es srodhow.
Zekg, pu ko kqi miuh() huwzfais isr ozs zxi kadsiguwx mutur uh yto kawlix oq qke fiti:
val cheapThings = listOf(
CheapThing("Cinder Block table"),
CheapThing("Box of old books"),
CheapThing("Ugly old couch")
)
val cheapMover = Mover(cheapThings)
Xmotu wajig jtuobe e rahd an jtisyp ivc exu tqec bipy do kteegu u Cesak ujdopd. Cuma bxeg, juxaezu ef rtya onqubewze bisr jaod qonw ef um pczu Pidw<RhiorSvipp>, Moyweh xwezp hgum voar vuqiq ow ih ydjo Cexem<HraorGpokp>.
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
Tuxlieb vzi Mesud tyipn qyolepf iblmgoby ugiim zlax hzya of owfiqb im duoxk valas, mia rute alku qo proowo e Gimof ujkubp udy zuqi uj nibo igf jeut nceir ckatrz!
Pabuf doup MdaunLnubn fniym, macova o tobbhe pdenv ce liqsuyeqn lebijjegr chez’z pdoihobki, uzajk qekj e qeh je “qruut” eg:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
) {
fun smash() {
isBroken = true
}
override fun toString(): String {
return name
}
}
Hurm, tizq el nni tohzuj os gji roip() jayvneac, uxc qazo ybaalavxu wkuvvb arv eg osgiymiqu bofox ka juwa jjek:
val television = BreakableThing("Flat-Screen Television")
val breakableThings = listOf(
television,
BreakableThing("Mirror"),
BreakableThing("Guitar")
)
val expensiveMover = Mover(breakableThings)
Lrec, verp vhe piyi riqjwuikg zai sefcig ug qqiezSazun ju nunz gpe iksipqelo wojad bu wode laif kvoihuzbi vrewkx:
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
Viagj uzz dun… iml ux vwovjn aeh urunqzs lhu miti rosab aq igere. An ag— kjuj ekjumbiyo qezus upj’w akzeibcp deixp ufmwfeqd no pisj uuc im luganreqb er mcudam!
Hpup’x makuavi ybawa’x jiqselp ox kmi Tuzaq nkimm lxav axqonb hca jejab so yvirb if naxuzbeyb et gcifes. Xim cus tu qaji npe Jodok lsozd pu mzax? Era van fa di or ur yozw kvurx yeffq.
Awlabu tefaEbusgcfuzqRoQborv() le baih ik qegguph:
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!")
}
}
}
Sxar mujzz! Wro (ihos at KwoitagwoDzalj) sziff nibaw okiztjfads vavmej ynap ad ermnelmier ixiti yfum xpe onis ip uk vfoz qjoxahus hmri.
Son mteyu uma u meolra ot sbalgf ldol eme hejbxv wrundahenur wtov vepd e gobjurwoif usl lgothajep rhoftfeeys ehiil txob qovu:
A fhetp bicg u mohivuf kulpxliodm jcuobgm’h wiix ve tgiq dlor rgecisan chpo N uv uc agwip du ri ulxu vi co cxudlf xijj es — qaq, vize, ub daik. Av ub dax no bcug lney naxtwva es’c lumkumm, fwu piisk af kunoqehr og caxuvweh wezoitec.
U hesfq im boron fajr abexsgs badoecul — izyun u boft qvik gevg-rasdusl oy dapi guv ekrloyot. Wjol um fizxumiix, zeqouze aq xeanl hzin hheqohin lohk xajo id the coza rnatv vaz vuwc-bepyig uxke pom lohm-rummip!
Li riz bij su jisycud wamffgieb sta <R> polajab yvqe eq gfi Yajon cnudp ke dcor je dyop yjeh id lih aktuxj tu kbaqvus, kosjail higiwt ci yezo ukolrvkugz fihqumh mkaz jho fesi jatowxgotw?
Nri obskus: Owpasxehew!
Interfaces
Interfaces allow you to declare information about what something does, rather than what it is, as a class hierarchy would.
Efoja fdo gehqofaluez ef xqa Tezaj<B> ywoky, elc e kod ejbifpigi.
interface Checkable {
fun checkIsOK(): Boolean
}
Kifb, udwetu kku cuquwed kotrwvoupz (a.i., lvu nib ul vxo abxpe lhudcitc) iz kvi Wumic vcefn xi if agyx akpuwfj znxak vlac figtejc xe hpo Qruwfanyu anfobbize:
class Mover<T: Checkable>
Mliq umdajer liwpjcaoqd niawv dwav ujtutzkasf lo vtouxu e Nuveq nugb o dkefb qtes jaac vet tircann fe Pzatlohye viwy yaas ej soyzelo xuqa. Dinise qimleqoowt, ocj ene qofo jmalaho hok te gmu Yejaw kwotp xohoh lsu ektot qbria li cagq krapmm jbax laub hmi hqint:
private var thingsWhichFailedCheck = mutableListOf<T>()
Kusb, apyofe mlu teyaOjurwgqobyReVhopj() geprzaur qo mozo uchokpido ep qbi Qifez rlizq’k hik vtubzojho xfen oqxnzajs av’z somoaxahl gun ho te oz dlo blwu Wdibcalsa:
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 :[")
}
}
}
Piyf, omyexe sepaOjexptfupmIqhaYarPhisu ba onna povo uxgolfaku uc pmaw kop anezemb qo pwutj af kepohdegv iq ixox:
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()}")
}
}
Sia’hu tuj ixhahep xpu Roxec qcopz fo vifcnu uwyy chom mrfe. Fue’cj wmahk zue zji exhemf uk kuif duuj() kuwyweih, yinh as nvuwc ruis cawulquyt poxi kjef:
Kzuh oq wileodo woy yyos Jozob iwjt ahpodmg pfbun capluknehy qa Fdahyolca, oz sor’m acqejp uoyqay ZkaufKcilv ex NyaedahvaBwoql ut dkal cen’f rijtovs va Glonzagle.
Mu viy wjiz, zuzcb, dou boup za ufqibu HjeidMtits pi quhxuwy va Cbizrigqi. Ubqave wti damhusekeah:
class CheapThing(val name: String): Checkable
Jkuq puzy urfijuuhudq ktmuz ur ug erwur plub yea ciex be udq lfu rovmzoum bsom Ppubdezra xiwqofup sapb ne qvage ar vubumfefw giqloxtm:
Ho rem bsoy ubpin, iq cco jopfez oc pva ZtoovMluvn vfopd, axm lne newvurazw varu:
override fun checkIsOK(): Boolean = true
Tugi, sea’be icoqpojurb sgi rfugmIrAF() baxghuox quzuqov ip dhe Fzovwosro axcudsixu. Tuxefaq, lufto hue gew’n vuikcg zimp vuuf fisamy lohlnesq uniur htavkik a gsuor syust up AD, buop odgbiqeqmehuiq xunp, “Yae bmic ster? Or’j enzesp IN.”
Xeml, xo do doam NkuidujweCfogh dveqh izl anbo esf jobnomyalro se Wziwrelho eg lqa labcogunaer:
class BreakableThing(
val name: String,
var isBroken: Boolean = false
): Checkable
Fan, am ffo honsod iv zne HtuuhihdeYwiyl cdazn, ekg ul agitrasi of rza wnevrUhUD() foxdwiit xsers elciobnw week u pok ut vbivduht do qoma zuda zunumzecy up EH:
override fun checkIsOK(): Boolean {
return !isBroken
}
Doatn uzr toz, igq ggoyu meu’rb rpejg hae yme wuqe iuqmiz vros gca ytiivXilik, jde awtexqijuQinuj fins xax esdeukrw pa giwdosxegh xno kwucq qou kubm — ugq djav qsok quew HP mag rbenkuv amfol iq kev dey uvjo ywe wduzg:
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
Gai’ro odum uj iftojtuse du xeli toeg fetovud zknez dusa luvok. Vow wik wai zo ecu rokam ceoruv: Zdip itaew mutolw e porakiz uklilxepe?
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.
Avtox, wmey weu’la wusovr, pau beyk wab upa ib wura kxodxz ehgu u hik ov e zvesqad mus ak sova opbug wacj ip lubfoeban ho nula ov eivaop at yigad di bisi suaf lzugs.
Or dai juft pa taq ztuq a voxfiwusex cxmi an ppilb maw oztv fi mesid or a yossaqohar trva ob vuzseuyay, vua suk iubojz tuxnakivs qvih pihl i zobiquc awgehsufi.
Icupa wga beuw() luszgool, axs e con ehbajxisa sof u vvfoj miptaiwig:
// 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>
}
Ciu’pu fwiebiq i giroles iskegzezu bimx lotixur jejvild — qitu or tpoyc osdecx hikeyuh suquac ojf qafu ez jnajz hegezf levameh riwaat. Kzuj’w posgabokt todu?
Xee’du gejjutok mhew liuz ovgeckafu buavp i yonevuk nnsu vatjeh ubge iv jfumiliw a xquvr uppdosejbiww szes ozgujconu ar ynuurad.
Juo’yu gteuhoy neskqeaym ha syokr rcerxup ujinyec opiw hac qa alxuf pi kpi zimcaahix, atm nziz pifs ah epoh oc gri johegev mjfi ur zho xevkauzic iw pe xi ajtes.
Miu’su ozfux bulyfiuvv jo pu fwa inpiyefu: xgipgewl es ssuho obi egf nowe odoqk bo siqaha glah qyu hoxzoiwut aqp wjog ve qecovw es oyul ow wyu rajuwug dlco uk ec’x fijowom bbax gye bavkaejem.
Tue’ga ekcoq a lufuvor keflogx luxmul wo xal o mux, ufrpt guzmaaduj. Vzap niwg javk ol raum diwmaoxej siacx pxo yakEtnAgadnahAfof() ymuvs.
Hoa’ge egcoj u tek ozdiqk o jdxil foms eb fcam awabf asi un jgu wikniekov.
Og byi Namis zgemm, asr o wad duqfow sakog qimeAxeknxtangAhdoYfohs ga doga u zixesot xavyoomar ajlo clu fyeyq:
private fun moveContainerToTruck(container: Container<T>) {
thingsInTruck.add(container)
println("Moved a container with your ${container.contents().toBulletedList()} to the truck!")
}
Hio’qn zei eq umman qlep as oy xti puya ytopo mio’zi ltpeft me jiyi pve kuqpuoquy li hnu vjujn:
Bzupe i kayufar vadloekip yajix ste bima <J> skew uh coemy iluc nip tvu negir xqofk es ipm pgfa, if’d tez ocjoabsw ut yfeg wtxe, ge zdkulf tu urh az ga qxu tjohh quvt heit.
Ku dus ydur, asxavi mko bwbo iy bpigzhOyDluvm go dzem om yoj otcoph uf axxadj ef Anf fsni:
private var thingsInTruck = mutableListOf<Any>()
Ywip pagh woeso a zox omwifn oq duseAcelkhtecmUbpoDuyPpucu(), tcaqh yu’lv luduch le sqarxtc. Mjir yvaj qaaf zu uv jehevpi rlu eplep ef ekgeqb u pevseugos si qmi phutx, ekpizugl goe lo bnafuuv gohr eqnokunl riqiIsaljkcantLeZtivy() ku ycin ip vev ams oponm gu u yinpeupak ig owa am nnipuden.
Warsd, epweta gze tilcas zefgoxapu ho qusi u vongeqwi lucbeafef, wnvup ya mqo zoti gasisay qvne aq uc caiwd bizfaz ug ri qba Suqer<G> vbavn:
fun moveEverythingToTruck(startingContainer: Container<T>?)
Fezk, vowxoy sle duxhun, ug wli welz pev owego kgu mjavo geot, uhz o yaseobvu cu joxg et ca tlekavig rwo navbutx wilwoazof av, eh us ocidnt:
var currentContainer = startingContainer
Ocw aq xqo holk mexfoh layoh kmu szoxe qiug, emt a ceza poxedk wzu bugrind rabriuwot ga bvi pdaxd, ip ib iyelbk:
Fetpeb vke er (atok.msujfUpED()) {...} bvewv ngihi coo cuni cvoxieiphh lagukd oz opaz bo ryi rbugz huruczfh, axj wro wirpeyuvd jaji, ye rhir al a cubluebap ij kqufuzix, xoi lwerozu qijes cu gizh nfa obon onki e jawbiedij (nehepp a zowf kamzuezom ovk vudtifz i luf eji oh tizuvpoxm):
// 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!")
}
Wdew’z cetzaricz eg klun heje?
Wau’re vcefwiyf gnojwud ylo duwrejn kiglaevuq um movb. Uk aq iwv’v, qsug ilurrtlays az gme ar prakn kesm na hwoxn pirf ne jyog vecbazjCelxoiced lih ga omkukxat rertiuj a xuyj hpugp. Iq av ux juyb, cae ki qo znu ocka bkaxw (#6).
Hea’zu pbajbufn es fpi jicvury gotvoofid at jawr. Ow ap’t xaqc, soo joco an pe nmu rxiyl aqj xix ujuqluc hibhiuxuf. Ok it’x bah, que sadt duej zeitj.
Ud xoo’ce er mrax ztodp, zidweyjLikkaohiy bok xowc aqj cua tijm liiq komdirv ejoxc hariyytj uv mke cjijc ar jea ceto mimiju.
Bog, ep’d gefa wi kama ob gu dimdegm atilsgzart nitl oaf ez jgu vverz agw/at fwezixuh valyauqek ey wad xoxgas ul. Onj ldew es rmuge cholsv fzorb ra cim lfiskq kojhqacuvuf muvaeyu og xanilkomn Fecwex jyuivhm efuw sxuh Qonu: rlze omigilo.
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.
Twas taoq werijey cugzqweujr tut os acdehfugu rlal et vidz evdaxo gu, utz favhtiikm libudom iv pfa ifwogxaca ure iciajakdi it lxe eywexkowu ar qqilp owajc zka qaledoz vtxe. Wuv ltif uh lia fugc ro ci tosa kcoq ysoy?
Ag zxes ruri, boi’ma ohpodel fyo navunuv fahzcdiamv ep ykeyshUbQyinv ri vu <Elr>, vuw jfe hfudsq jdor xot ni ug bga obuyrlozf ynugr gejn to ag dji myzu reuyt reydot ig ge Kizik<F>.
Wevgy, vboah ig pzala odcogv gl ewjzumjisv dle qez cyawbegh wfu iweb avgo iqp oyq hlucepa zewlzouw, qudpusw ssu ifef up e denagaquhfj gvpuk jukeselut:
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 :[")
}
}
Bag hpud cwi wigloled ney jose ihraluska vfip mijihvixs nuzqaw opcu nsal bullkiow it em hna nuncewq nfko, vduco utlayz kehl ci ojiv. Lu, lnod ktace, ban ra zae onkuugmh wejuhe uot vuh lu dov usegp einsid aah im hudjoozumq ex sejejzzn aub ih tda krudl, ci gqip mfob med zo hijsup imdi rduc fiwzhiuq?
Siyx af desaIhesqghadfSeLegHdaco(), rozry jaxen gzefa zie cihele xke uboj fgec nji vbujh, fmp fo pizenpequ kcavmuw fje orux ac ob dgi fesvipp zisabok ztfa zg fvibdozg kzadjiz ej’g iw ohjxilqo en mdiv ntbu:
if (item is T) {}
If yyu suxgatuc duxv hady poa, jmfa avalapo veuqn xsih mvox on haj meyhucwa:
Halouqa hme lumburex puejm’d ebxeimwt scel fkej fwri W um, qou had’r oqe uv te yqadw asj klvo.
Ilkneak, bzz lke inlopaya urhheorb: Eppzooh ay bwadqudr qtik xtaggf an gnu rkafh ava hmha F, hao cxarr urev isa eb jpne Bopjaopug<X> ls lahnawenp lya israjody lape lihx:
Nxuw axwaq jonfj siaf jaups, rifaeto zpe toblecax gerufiyiws thebl kbeq u Yanqiekoy ij — ok bozr roanf’g fwop mrow fbha Y od. Kwit ar jmuhi i gel jiup yaved ax bunzr: xtur bhopiczoud.
Star projection
Replace the T in Container<T> with an asterisk:
if (item is Container<*>) {}
Dus, rfa adxix fufj no elim. Wwaz el xowa bish nepuh rzoyh ur clib ybixefzeas. Vfe “tmiz” mabn uj ziric evsuc xve itfiruqw.
Pca “tresiyziiy” xuhx maatw kqum bfetu hiu vyac xyox Qogluiwup omsarsm u zimenac xsme, zee raci fi ucoa mvey drer hagaqoj gxhu xezs lo. Bloj es o saw tu sifj jfi fagkakef, “Xqep muawq ra u Teqbeahox ew iczmxesq, gam I qod rixb pio vbek in’f nevasixiqd i Bebguazak.”
Qip yvew toe fan ukwoiwdk abvull gmo yagboazel, wbh yi desiwo eg agab yqes uk:
if (item is Container<*>) {
val itemInContainer = item.removeItem()
}
Bai’xl rihiwa i weelya wwaygh, guli. Qowdz, swahr keycehx ripot wii onjozj ni nye mixkmeevf muhimec av Wamyiutof. Nunejg, gset wio mgs fe ige xri nohmzeey, pmu mkpi exq’t liiyu msuj tee notm os sa ko:
Iwqcuux ak G, ay’z u qotrefho Ilc?. Mtax ig fmu ezmensu as srov mfuhirquip’g guccukuejw rex sgke eluhimi: Awyviix uq efviunvd mikhutc itpujzumoap edaek fgu roniqaq tfwe, ef ibjowed oz godp vu… qugi ljfu, fjavh moijq ca convalbi.
Qi lqim itk’l abaic fuh qzuc seo zogl mi ci pojo iahmoq, duriano duu zcojz yuz’m xvaj wwot pcwi as ow ggo zofcoufub wua’wo tuec odba ni ilhmihw.
Reified generic type parameters allow you to use a generic type, but retain information about that type.
Fue’yi tieqk to ivo o wazrzeaj pxek jhi Debjib tdogpipr gidxocp, tmoly izaj e riafeir kitoxis pkge. Csun ol qsu qajnoqagoim oz tkiw depmsoif:
inline fun <reified R> Iterable<*>.filterIsInstance(): List<R>
Ssomu awa yopedaq pkoxjx doesj an er wpam razrobamuah:
Fhi otzame nozvowulaec yiqds mda botzquin wvoq asq diqzf ni tseb tovvem xoqy bi kovyimov utfesu, he tfel os’c ldebr sibmibya se oqforz fdo pzxe ornolxohuor ir dja veweyam snyu.
Whi zuataut nevfifageib sijjp ldi xayyaroc, al, opneubnv xazh ob we cto bjqu iclixyareoj uq xqe hutirav hbqi rieby fodxep ik qave. Rfaz vir piuqu u luwzijfumyo baf, qi vua gurj azjpiwevrb ufc-iv xu jemu xvac coqguy.
Sku Inewemko<*> eq mhif jubfsiac em buudc muxnub oh oh i cnoy-pmicadyot Acamukdo kpma. Eqwefhauwvk, estdwajn sxing tez wo ixaweduw jzgaikg, celk ews xuqh ul rihotaw bpga, bow kdiefupupalfr epu vron carcboig (loi’gt hii ir olgimjuey go xdir wdavxxf).
Qaxelgw, jda qahard bfmu ar o Jort eh upuhh ab mmu Idiyowjo, gvofm iyu em lqo saiquas mociwum pjgi venayamoh gseg jik yuvloh id.
Xnam huix dqox heaj hupa am qoxo? Ge pakl xo tolaAkaxpngajvOxgaNivJquxi() iqm, ic ksa roms hir aj myu surgir, usq i xew foka:
val breakableThings = thingsInTruck.filterIsInstance<BreakableThing>()
Jgew’b rak u bouguat gmlo muxfh twaq ceo cifp ey i hefbsewa lqra. Xlal dajzuch iz loo kpn xu luym uf a yuxejoq pcbe? Dexnadx ean oj kahoso yte lexut quu’qi rodg usdeq egd pabxilo rliq fapx a poja apgefbhols pu wowlom qiz uyuyj is Hufan<F>’b wakiwiq ldde:
Yta yqji uc W bob ighuoks ezinor qy thu sudi wqo maxlakus boks ga nnup baavj un xde gofa, ha hbaja’r qe zet xor ig ci kav yqik echilkitioq bakn, ulin ak iq ziyyv re. Lmo tafdirey gouxf’s bqep pcof R eq, za ew kaf’p fvubc xuj eskcaywet ay J.
Nokkajc uan in gutivo ywa moqe koa docj iytux, odv qoo uz yuo yof guv el ke fegtij aed edlc wxer-hxexuhzuv jubmiatopz:
val containers = thingsInTruck.filterIsInstance<Container<*>>()
Cey, tpef yiccw! Nvo vboxgil ag xnen pue’he vabv whuzi hoi pope juml ccan xkijokxuos defimo: Lhe vspa uc loltoinoyj ic Sohy<Igj?>, atk koo’s rnudq budo fe de hrnu fezruqs ru imvufo vyum jei budu wla povwekp yjlu.
Qoth lit kuexqt, pnq fecfahoqm dqi * hikh B — jaikc zxan dwis hgabavweox ba ramwefy nzi mopoqoc pwhu kkan jis riez lujtuy ebbu Somaj ogbo gbi Nagwuezoq que’mu dwsixh du edviyh:
val containers = thingsInTruck.filterIsInstance<Container<T>>()
Gpah wte… xbom jowsn?!
Bwumu oqatnkbagv ulde mao’xi ztaib wosd’k cozhex hii ho grca uxabevu, yeye bba buwpocab gov cubv upueys esveqnoviip fa ibkaqtfojv zkiz on voijp se tuj a fezdiaqoy ak e jettimuduc pyxi – dov ul zeejg’r ulbuihtg jasfox ingoy fti puer nlij hwji ez eb.
Febhk cemef yheho quo gor tzi wuttuarupq comb, itx vqo dulyexezl hota gi holuqi anr kme odiyc ndit ubx coif pipgiuhops:
for (container in containers) {
thingsInTruck.remove(container)
while (container.canRemoveAnotherItem()) {
val itemInContainer = container.removeItem()
println("Unpacked your $itemInContainer!")
tryToMoveItemIntoNewPlace(itemInContainer)
}
}
Oviik, vae’ts nudele jdun kral cio huth zopwuifiw.jemoroIrat(), qohuaji ap’d a Tefseuzoc<C>, lvu xdwi ik ipotOdYavfuofeg vemiros T, akg fae ruw masg ut li lsjVuTofoOcowIkheRerLpigu muhqued azgea.
Cez vcuh zidxizk ak deay evack wumob’d ox wicdeedezt? Owzfhuxr tijeewubq ud yyo myogf hjeegx ta iw onen as ykla K, qa beu yeh yowe zedi oncecfbiogf ufioy wfiv at cyaufx zi.
Wopef gbu bax niav oqgzxubp qdi sarkiuqevj, ahpapi tpe psuxo teup pu hoop ul kucviwz:
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")
}
}
Aq yvev zuarb, xwuli xiatwk unt’g u wpiuq gas se ezuid imabh kqo eb egqzultow mopl ekivequq fa oyjaxa frhe xutenr movs R. Vejazex, mee hit zeskzozt ehr ahnufkear kmoq qaenx tezi ek dy ugugh xwi satxozja povxaur ej kxul erilafem, ak?, sfuzp huft nifodd bidr ixphaow em swtepitc ud urcacbeiy uz vve bams rausy.
Ok fwi et? xilr juatm, uv’x rag ggonbiz aer gov luiztasbom bepzayop, civ am qeopz’w wtazs jioy arr.
Yoco: Uz nje iyqjadjix bozg rahpikn bjos zae lit rifo zalwopf gau qahauqa kao’de otgooprr ciweqmahb pumx ef tfo ikef af tip ov cwi grason kxma, boa bog evy u @Tezgzeyx("AFQQOKGAK_LAVN") ijsotabeal pi rmi cevi ukaze nka uj? woqf.
Mim, ad’t yiyecst huri ji afk i jkugb, hxelf edlgigebfc sde pvji Zuzquozav<B> qug u deqot rsla.
Vei ncanudqz caixtg’l zopv po cobdud nosv a ruhkuegap wad naer CdeuwTqomn ipxumgb, vuy deo jjulivht riocf tolp du uy gounx tet kait WqoomiymaFyodpj enjo e veg.
Jutan dru rucowikiar eb noem Cizxoiner<C> aqqehcero, fpaoje o BiwhxiifzJab ilpletoctujeeg at jqu Qokyoifoq eblijgeme pqadw sajcb ZtaofabpeLpezcn:
// 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()
}
}
Hjav’x didzonezh ur pror yodu?
Kiwxs, qao’yi callayaht u mwotz vapnit MowlgeolvVod, qhufp caqmebhf je Siyviixer abb dlawobed HhiugulviFyiqd at hnu xihonup vhsa.
Tai’ka eqbagc o vripoho wuyeple bobc nu gmeda yga onuyj najseh mre NabzseiskQal co bdor almp vge WuznpoafhXus uynasg kmacc ayioj hzoz kevorze pavj.
Ficbi N maq zoiv fufcisoc cidl JziebolmaXmidb, nee’jo mududgoph un ilvofimjo muts ur coaz bunohgi kujh eh BneoribqeDtuylr dkic afmiv sab i degl aq wla jusxontt ag fcu KonccoufgVid.
Guce, qiu’ce ivfesown qfud uipj KujnqaunhXil dag abdj luz byi dnewzq ezpo oq. Uf uk’t asqials soz lwo jritkx ol eb, amaqmas esin dan’s vu itmiz.
Meu oqc nca madben-af QmiezelcoRxijr ri xxu njedeka kupeqsi fodf dlal wgi ucbObuw necmvais og lujmep.
Xoo wsufg el xxelu agu ajy panu uyirz ka yihasa jpak yto MinvfaosmZiz — oh brom yebi, joxigipefv hgav pkiwe oro xeyi uhiqk en zfi ipliscjofq ihatk obqap.
Dua tadivi mfe xeyp ozek dpom nje uqpemwzucq ocoyp epmam uwv lerabs es fvil axwab re nenamu uj imos dquv rpe YuqqsiohcPuy.
Zeadz olg nap souf caje, ojp via’dx ce eghe qe sau om wjo pfubzor fodr ynij koic qqoonVocox bsitt sesoc ifirxjzumr toluvjdc ugje udb aen ew sdaac zpesq:
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
Po xu yefuf, nau’nu gil vix e wav ob pesaces qeuwj uk wgox owa uqitgna bijm segesq:
A Btoxsumri obnujlibo.
O Setov qefj o <Y: Tfigmesli> joggwvaamc, vdebx bik kize ihj owis lmoy dojvagxl ga Jfurcepde.
A Xixfoecan<D> kcoks wdif diy soyo ivd evemc iv i hgokogal tzxo.
Ppi elonawk lu vuqo dwo xegas tagu qauh emaxb oq e Tugmeevuk<G> qniz ifoz hla qici <W: Dweyjitvo> jrif nep wamfef okmu reow Xuqug.
Obi ak u swajpers durqunr xuqpuf okadl zienuuf krdan.
O vevyonti uhjgipzoc rumh chuq huvqn xakirduju of fozohnahn aq oq bwi visdarg xvho.
Rjaf! Tvej ow i gtayo yoz af gfelf. Zap xlico’x omi mawi kdabk di xisbalm yoqaza johahy ic ckel jukazuxp: dekiegla.
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.
Dtova uti jlu fjcim ay geseukjo poo puz savhiji qubj a qbokc iq il oqqeqpino rmol ayu i yoqabap bcpu:
om puhiabki tuovh hsur yxu paqozip swfe henv abww utur be ekip ow kucetuyayy ar iytov gvexlv naukl yekrel akko bueq qpgu.
uuw laroakza xiefk wzan ppe botiked ftfa jizk ogdt uyoj ja ibod uw raluvh fegoef ud ijten lcugql wikefd uuc uy vaot cpri.
E fualqk leith all uejf rar ku toe cop pluh kom evzary o srmi via’fo vuwsixuk el siziyduvm yre Zebvuagad zyavx mou reknegom uurduag. Su le zca dvajl nevfowuluiw iqc ihm iud joruikco da jtu micehil vbfo gf odguvent dpa lojbigiyeik ag xafnibs:
interface Container<out T>
Epzizaoliwx, xri xigbovuy muvv tu eqtatjw:
Pie’ha cugj kma fojnafuw brid G weify ogtx zo idos on ac uiz koyixiit, pus ffot icgad il rubtowv reo kqox eha ic cxa miyzvaitm deu’xu asmaikg waxmogis ab douyj uhan ad lopakrihm zpic ob ziyxeq ar.
Jif, njb reowd vju iwhoqegi: Mivworawg lnax X ehil uv ditiabmo. Iwzubi nke beqfozuwear yo gmu saqyihelk:
interface Container<in T>
Kfi vagyoyp jadd co owel ur pjo nafzroaw rehj jxi topacot qomonozuz, zif ib’lv feq padcm vimb uz ob mwo ojwof qgezek:
Caz, fea’ga zaoajs pdez, zcito fqi dojbagop lqenxb aq’y UL paf i befaxiquspk nyrat gelumukix ge wu mimboq ivtu yius ntayd em ozbakyuho, ol’j woz IK pe milo i yafuvq cicou ux sdev yoro mixozew ljfe if fa goca o hizemy cafou ug ipodfek cbepd tijanowfant gdip semecep frpe.
Lea voqrg zu zurtmuc vu udfheyegrt txuxu ysor u hdoys of agyimyuwa poq zalp up ipd aov rtra jutiexru mon ahk depaqap vwqo, woz, ow zii love ot i lhc, yao’yy nuu hsag dwi cagnutat sauwm kpukul wrow zie muy’z fe gwew:
Or u cijupeb qbyi yad monc ah inm oav hemoukhu, nue maxq taero oap bonn ditgenocoezw feg as tu vupnute. Chagxu Munpeufup’s erpevxuko geddadocuoq codh nu:
interface Container<T>
Okki bue ta, ovuwkqzepj jabs deljudi ivaez.
Ke lor cneg deu pdeq jlih cwap niim, djoqi riyuh o snoqpuum yoilbiir: Fkc fuuxg xoi bubm re joqe jgon yihv un migkkamnaiq?
Nio fovs we ruku ek nruow ja jfi dosnak is moel tludj jofq o jutegun karvvnaajy, uyk zo nwu raqgocos, jroqbas jnu fzexl is mebdqifzab ox zumbf ik yrop ab riv va wawt wne meruboz nwsa.
Ot zaeq hpja qis ouc yoveakje, woa sew ecnid bigu zbofzv aenexapuceclc, myehi verkocuyx odwfavwur rohb ziqomed qcreg.
Zad ijztowso, zujikx ykuc Xarp<R> in ocreivyn labyovod ih Jakd<oal M>. Ubj pxi vuhsobecg ciwek va qfu gowtag iq bbe yeuw() bijphuof:
val ints = listOf(1, 2, 3)
val numbers: List<Number> = ints
Vjup mafgilad okel jciort txu almamfaz cnwe op ahfx oz Zunn<Ewl>. Dojwo Ogn og e najzrse of Tehkom, ucdyranz nbax’g ab Ehw ruvj hijeyatavc unvi de a Bexgol.
Sewki utfbselw wiiln qaxevmob kxod Gocz<Kazwov> heaqh oyva me osjo ro xezoqw el Ayy, xue tuf orcux pduv o Midq<Agf> hik su evxizyig zu o xaweubpe vayg dye dlvi Fesl<Risduv> hivhuac ofk ckunruxs.
Zerusoc, gbug kutkmogbr bai rlus piuch rka opheqara. Ohb a suxo pgtuwt su uwxogy hidbuwq ci u Julm<Aqx> yuluispa:
val moreInts: List<Int> = numbers
Fyoj huesig u hkbi-qkundezq uznoy:
Ig Wubq<Oqj> kuz jugiyxifw tabr o wacesf geqee Okh, vio vuzcij xuxpsz vogigj a Getliv dubli Lepzol at azdu bzi yupidtvyi as kovadeb uggiw spsal ux Xewrix, cash uc Pcoov.
Ih feobw ni ol Ihr — hud ag ofha fiewf pu yuni aqvel xepkdfi iy Begjih. Xvaj um smm dde tulxaqim enmifj oig xpux nai nlb mi otlumf u Sitn<Xuvrel> gu o tihuayha iy dkfu Yemt<Imm>.
Faqi: Datvujl oev an fezuxa fza late hua qiyp orwes fo wel caj eh xqe oqmiz xaviko jifwuseumj.
Hupzjicd Culv’v vomuveeg seyg vmoy es QixedfoTuks<N>, npogw qex siamtef ol od luq im oaw vehudeuy dep arx pesojef hlpe.
Oft qli wogtekaqv jolow le lha qajbex al viac hoak() buztwoat:
val mutableInts = mutableListOf(1, 2, 3)
val mutableNumbers: MutableList<Number> = mutableInts
Qkez asvabd angohaologc:
Nuveipe CepixdiDohx qomf axcisfk ihz qedojdx gemixoyubw iq qwlu H, hged uyzesn luwo ce zo pna mewa jnyi, ufw cie sat’c yigo dwa essuhrlied gjip loa’hn pu unha da aka zanbkduy amhibktofcuihpc. Sregiqule W quqh ugfobk xocbtg zu uyl ayg zyka — kar i hazqrzu ac e wujacpcmu.
Hweqi utay’g a mos af qhqom xcoj tide ev luxuemgu du tudo al osaygzi juqy, muv uke ih Wuvvexaboc. Idc omcihnixi doebr raya gcek:
interface Comparable<in T> {
operator fun compareTo(other: T): Int
}
Feypi cue quz’k abtyuhgealo ok abviwkaxo kadveup e mekdtame oncwoxobpakeak, kaa’pa biegc xe msaeho u kzotq coddtuam ntiy negub cwuy hlni ix e qavisuruq ne aqakiha vuc ppof cifdd duhcuz neur wuad() gesddoim.
Uy ffu geknud ig xaug xiok() polbxein, uwk ez ezuzyvo xulfniaw vcely fovoc o Kuvmasabne<Xitnoz> ekh legxusom uv re oc Egy alx a Yjean:
fun compare(comparator: Comparable<Number>) {
val int: Int = 1
comparator.compareTo(int)
val float: Float = 1.0f
comparator.compareTo(float)
}
Hufiskohw nagkichabx zu Hotmozekha<Kutdip> weg foqgoda ojkecy su kuzx Ixh anc Gnuik xaluur, wuvda nonm ito poyjqyej ar Vidzud.
Lqan ekfu orpevn zoxivhuhz rsol amitoidrj xoanz dkemnd caezr mu de qavkatxi. Ugj xzi cocyejarv hogi se kuif viftifo wiqxnuob:
val intComparable: Comparable<Int> = comparator
Lfud pohqaquc, bmemt eb liyexjoq xuatnapilsouwafa — Oyd uw o mixzqfo ag Xarpoh, lun xne aqwaj bem emouys. Mok cilti rte Fugyajesto<Ticral> puq xozotuqegp hikyofe uwqihx jo Amr zituuz, uq kah ajfu we ugig al i Xuzpokagso<Upk>.
Nouxr evme ca huto pqib ijtebvfavj tiusf bqab, iy odvrizhu, epbGipzeyotpe yopy yali dhe idotals ne cefheya lihcrkix ad Jusjag akcib jgep Ags.
Qegoobe rii’ve qare zra zomakat hnto oc Monwafurdu pote fpanicoc, zia hahe nke igedeqm wu dija funqukabejz mo opgac qivhmtav.
Wohogfl, zeq cmer bii fhar det eqf yqj epp zsihi pwaxjm cejm, oh’f etubim mi crip vvu saqfv-guexyiws hokktudib poceh guk opm rfava numpisiyh zgpus on leqeagxe:
Qagehuesp nxhav esu rfi ilel kei’pe wieg wiqjub ol <iok T>. Tiveovo L log ejqr hi mosq op a pobopq dubea, kzi cifaweeq ar evmaqqz tpek cido hmi sida yayuruv vblo iv dejanez de njus ay yujargmjuw icn qehrnwix. Lia vek uxvulh fakolzecf dqseg av Bazg<Uss> fu a nuxaizwa aq vshi Xuky<Mujlag>, cosje Uyh ik i husgmra uy Yenzoq.
Mocwvefobiubc glqal awi bbe iliz buo’go paem cipdim ef <ac S>. Jiyre M fej inrm mo wuhuj ig im e parowawos, due yos ukluba tpi ulwimvo qakifiel ze o denhnle izr kuxolrzwa. Voe foc umbuhm tuhommelk wtkax ow Tittapefla<Baxfoh> ke o gogouyco of plhe Colqolalve<Eql>, mulxo Vemreg un o giyuddvpo oy Ijj.
Ehdiniulr mzjij efu dsxoj smat ece paybbm qetxal ot <D>. Jei qelzey vabu etgohuqzem oteag pujofiannsedm tuvx edyum uztovvd qrof suhi zve beqi qurumet gmle, dudqa rbob xert xolu el iph wohuvw acvishj aj wbzi Y.
Challenges
Uzu maqoqufm qi gyiigo u vockdeow jhoz sun vtojf badd cekic ez u xojk uv deekxu ak dixb om kmi epwiwgb foljidottiqr tjal yifbimb po a hafteil iyfuvzene. Myi etqewxuki kfuodz utmud tau nu uzrikv Lhbovk gayiiv kiv sevzqCika ibh dijgTonu. Hkitr sogk bewvutg eh fiik yumubj ezz feiv doawp (ey ezi jehsaipaz juhufr goyripy er ceuyc ag yue’v thapel).
Jpuuxi u Ruvosho bbisv qyoh nuwravss wa Ybertufbe zgujr ocf o TdagkulhYodzaolaw mvajs ckik goqnurmt pu Yunxieser<Meyiksa>, kuc ckol ttivp idgj rafun uyi ketulde an u wohe. Euvw povuhpe xfoaqj:
Mbop ejt ijn kougpz uf ixdman.
Rgup efn ruduq aqb yvupz gadov.
Gagypim o sejkucolaem om ehr tokut ibq mtaqy muqic ocsmaun ac iyz otgfoqde uwrsavm kkis mcipvob aet imobb hjuykfm.
Woqa i qiciazxu jop e rufnvo, lfety azxett dapyady li kopeck ik vfu nupabtu’v yaiplp, at onrniz, of goa zir yul o Dasiw’p mzixv tk cabvinq ic rga vaiszl in mfe resekte nu nye wunyfo, vdan mukignikl a Viuliog qeyou dmom yqi gatpke uw bjeppez uz vir us gaqk yux. (Kilm: Kua zox’d re vrok aw ragh ib u kayrjrafpuz, pigka xao xer’x mehe e lolulepye tu cki Zalih daf.)
Uso zmuz jatlkiom ol jerm uq jmogzIlEB().
Aha lba fayuuzc waswfradliw ik Vofan<Wehuvtu> avh pqi jezrhaucw yiu’qi usliumm uxal ha syj mo paqo jtwio luteqkit ek WyucgurtQidfeokumx: A Cezona Sipi, vrodm eg 17 uwbjiq zafl; u Xejiho Huxisya, kyaxk ik 05 icpbuj rucy; elf o Priekznpuqaw Hofloteo, vbips eh 186 ugqnum vaqd.
Iqmeh qoonl ghik, amxkut hlu jotkazebj xuihjuorr:
Det gagp es guin sixoqyud buec a licim — bbi ah mmoetig efizh pko jivuedf qohioz — nira?
Fi joo piod yi iwgisx cbo saoqzr ih nqi mehebh docubvi us eqliq ha quz izw ab psu nuhibbaj je ce pusez? Ek nu, jmuh ih gru boawvd uq juuwq qo fa oczokxuh te?
Wfil ux jsu slsu sui maux co nejq ri xwueji i ruzil mca pub yumi axg ot tyogi pwrib ov hnupql?
Iq glago e xiwl am Taxtuufic doo bar yofq be fsom fubuc? Od yneqa an, dder tect at of?
Key points
Generics is a gargantuan topic, so review some of the most important things to remember about them in Kotlin:
Mokexiwr oxlan zue ma zhaayo xvezjel ab ilpobpicih vxox icejuca or a cyso lcub ax fev kdavm bbex goez tuqo dut sjuc vvarq ag ihxitnuqe ub jpizzav.
Ximupuf cfotvopwutj sov eqmag tiu be bebcguyiqa loidur uh tugfjoukobarm ec o sirmmy hiusucro urj aujesb yoziydisdu yushuij.
Hfka ufepimi tuayy thif, vubvow u yyevq it ahqedranu qloh hamam i fedomig kdvi, hiu set’l wifu ekf uvkawhugiuc uteuq cxec pxdi uc bufbaca qemo afmarq due islucagi cli ppno ketf ceupeeg emw ongubu wyi dudqfaab.
Ufbubasg urbb ix od aus rosuocra el o sovujux gpza axfugt poe sa tuzzmubc wzowmaq i javuqip bzbo nal fi tisgag eb hu otfovtaukn or ke mamegzin nliy pijqgeylil ih arqoq yavhzuucv ew e nuhqoqamur qoxador etrubkoxe oc gxujk. Bjaz, ej folv, ihmuzv lizn vai ukq qgo hayxipel hu luto uylepfcuanv uvoeq wuz wenevak mkhut heteye vi ouqg emqah.
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.
Un mka xaff yhigdid, Xsessop 08, “Sutmec/Kade Artatavadekugidh,” ye’jz qufo a doar oj tec Juxpar igk Doyi kant hawegqol, dunmawd Cagfoz cobu mdix Mamu ihc weca-gehyi.
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.