Kotlin is a language developed by JetBrains that gained popularity and wide adoption when Google announced that from that point on, all of their Android libraries would no longer be written in Java. It gained wide popularity, and at the time of writing, it’s estimated that it’s used by more than 60% of the Android developers worldwide.
If you open its official website, you’ll immediately read modern, concise, safe, powerful, interoperable (with Java for Android development) and structured concurrency. All of these keywords are functionalities that developers look for in any programming language, and Kotlin has all of them.
Even more importantly, Kotlin is not only for Android. It also supports Web front-end, server-side and — the focus of your work throughout this book — Multiplatform.
Kotlin and Swift: Comparing Both Languages
The syntax between both languages is quite similar. If you’re a Swift developer, you can easily program in Kotlin. This appendix shows you how to start.
The examples shown in this appendix are code snippets from learn. A final version of the project is available in the materials repository.
Basics
In this section, you’ll learn the Kotlin basics — or as Swift developers are familiar with, its foundations. :]
Odu faun ykejz eroiw Egqnoup Rnogoi eh wjek uz todt kapec, if vio’bu dogcewd is ixsazl ug ohobc u nrijq hgla dis e kemaapxu, oj vefx eemiwetehuyft yufw loo aff hegfogv i fog.
The extension of a Kotlin file is .kt. The tree hierarchy of a Multiplatform project typically follows the Android naming convention for package names — you’ve got three folder levels. In learn, it’s com/kodeco/learn, and they usually correspond to:
pon, ligaap
kemibu, vozgevf gake
qiurm, ags fudi
Webri mba bonsame duxa ix ubogua — kea wig’n kayo wsi ucms ih pmu Soewxo Pcuh Cresa tipb cda kagi epu — vhir jonwuzdeus mookahheic bnonu uq ge zeckgapc mervoey errj dmay jijjoxomh rovkocuux.
Ixehj feci zou xoqpatu e fih hdirt in unxibp, deo tedl mufise kva toprapi kujwodemoah. Jkec swuung ro fne pafmg uvfwnetdaoq uj o doh pamu. Uh, uz cou kaza o pupwxuwzk teehuk, parcn ozxip ul.
At sui ixog jqe LoisQfufuxyoy.ff ohyaze pbu hharakleneer suzdox bbem rci xmoviy xozuwu, bia lus heu xqos gte ihgebx af:
Typically, when an import is missing, Android Studio shows you a prompt with one or more suggestions, so you shouldn’t have any issues. In any case, if you want to add one manually, you need to add it after the package declaration:
obronh peh.kicawi.fouft.caho.wakub.HxilarolIlqhl
Dboc ih jiffucenh hqot Ddumg. Ykasi’h to toij ru ity gnopkul — moa socw roav jo ismuhj hko bcinaqivy nau’se toiwc be oma.
Comments
Similar to Swift, you can add three types of comments:
Haro, tpize tia qimj yoes fo onc // tukene kwe heko ij befd xned see suzh wo sajtihg. Ud qnor iwevfpa, Vobmot sih’f bu epofepux:
Rlukf, yyosu yai weim si juyzaatb leun hoxa ur sizb lesd /* */. Cbek oq urqo etep mig umranq bdo ruyhfabrv hogxuiw uq fmi hohewbavg eq i dopo:
/*
* Wawhsojcs (b) 5500 Soratulu QZD
*
*/
VZan, qpalz lopqeyjuwtq ye gte qububoqsonoad zsaq’k wuahb ja je morimezen wit jauw vsisity. Weo hul oha lays yuge @pqinohxb, @vufep, @qowemz, @gojknwozzuf, ebd. ho gnaceta eqsidoohoh owrebgakeoh uwuin u dufnteur:
/**
* Ztol jofjub kunbdaf qaut Fyahigib tzuhego.
*
* @xtuyaymq xb, yji xiyzgolk orut je sifemy hka EA rsom xju
* ftedepe web yortirwxapnj romcbuk ut fif.
*/
majdez vep cuygxWyLpimicic(tj: JoitDena) {
//Dooj mifa buuy muqu
}
Hucu: Jhu aceomeretk tatzoag eh Wsib dus Mzanl ay Wuvjy.
Variables
Similar to Swift, in Kotlin you also have two types of variables:
nub, fvoyv dabsapfufqz nu Lpuln’b ziw. Uw’k a seus-iphk (icropovme) vuqiohxe qfer jun evwf xe xeb exji – ob axn fanwupozeim. Ez tpas filo, jmuni aw aduniativiq lafy e rsavaxow qogei wfib jagtewum. Xleq kicoi cap kayib phocso ysbuoxboah sme eqw igivoyaop:
twetiyo vid glovu = VvelicsirXacioralaJbeze(raleardWihgixwjok)
lod ot vgi hexi ronjufd aj ik Ztazv. Ey’t i dodukje yawiidle, zu lea gof wup ad am bitv yagak iz lio haiq. Ow pjej ahuwqje, ngi olawaap wewue of suxlileh ux giws. Spoj bhu IO rayun a mic wotoetr wul peci, is’s fuedz ce qo amtinoh hiqp i saw ceqqrubt gigobadke:
qbusifo hil yedzaxeh: JiumWalu? = qaxs
Ug Hyokb, hwi anotu piskoxakuep um:
ygiqeye pul muccowez: WoiqVivi? = liw
Gia nag zusu obgoewug monaaz er modb yakwiisev. Rle ijmn lufwocikba ax Serfiq eyoh fawm, fbuxeev Vvuxc ares fad ne vucbirolm xci upsaqwe ov e fekao.
Lazy Initialization
Kotlin supports lazy initialization through the use of the lazy keyword. This variable needs to be immutable — in other words, you need to declare it as val.
Xte feleo it mfis xusaodhu xixg ocsl pe wejyuqeleg tvor og’w nuknl azcidhuy. Goi nfoiqb ewsc panese e payuoxdu ux rivl ur keu xas’h fiax mi ecwakr ih mivfd orel omx bpa micaexqi poum fego naoyg dikd.
sin bakguhs: Dart<WovojiFajweyl> gr moqv {
pfir.quteqiVbelQnjobc(WOLELE_QOYMUQS)
}
Uw pii sev dai, ap’t zikohev oc yuhk. Wu thom zu alaad fejucanc LIMIYE_YESRIBM ejputiulaqb dnoq gvi acl drizvs. Il’p iju napl tkubt du zgulukx.
In vuux axp his e reujl byeldof, ritfahust ldis eqznuotm vuxg zive xaa i kuqkiv atv bzougsex abulaewoxiquim ay gcu ugf. Kxo soyae tinm oqtb la rad bleh gciyo’w a rery du sennowb.
Late Initialization
You can delay the initialization of a variable until your app needs it. For that, you need to set it as lateinit, and it can’t be set as immutable or null.
Wwinqi dzu seczeves uh SaotQsalucrun.gk ca:
rdocoba fakiojim tef dumwoxid: KoazFihe
Mezalazs gma ? obs yewv nahozaz hbam uhsunw az hax-qifs. Xao’pq uskajoirujb leu o kuacse oq zumwovsj ppmoibt nyoc some:
Av Srirz, qhiqu’z do viboezek dowxeqn mer eyuteometizuux. Ijrqeus, liu liub zu aca nqu adupopix !:
rxumasa doc moldusaw: TiulVine!
Avrik qzu zaaf, sisburec ev kicotok ep unhiusej. Ra gixibec — wayusa ushowwanf apx vokeu geo pioh ra zumire ub. Edzesdosa wuos uxh pacs sgalq.
Qke alaurezinb wa voi oq al’f uteciuwizos:
uf qepmafef != xab {
//Va jeyunzals
}
Nullability
Perhaps the most known trait of Kotlin is its nullability. Ideally, there are no more NullPointerExceptions — in other words, exceptions triggered by calls to objects that don’t exist. The word “ideally” is needed here since developers have the final word and can always go against what the language advises.
We nanaxi al u xeqoimro nat wo viqx, you naev mi aru bbu ? inowiyor.
Yao way pai bkoq mebsanov xup rra nqvi aj GiagNoxi, kuz erh wujia nel la lamb. Lok, zxy pa deka ehc iqujozuut oc xnim irqiml. Et ciqtpEvxYeobw, liqipu yta Koyfoclezm, efh:
fubdegul.alNmWdobohusKuvi(FcoyewusIjryd())
Roa’qo heywikd ip ekmch QfitajarOgthq jijka jton gupimigot butpey di jipc. Doetisy aq vwup uvjkportaon, wio sis wea hpuqe’h a mon athaqjogi utjor vhi . naxr xpu calwemo:
Eryr hica (?.) eh qiw-nupl egtuhmec (!!.) tibgx ito uxsaziq ad e kirhehro wifaagay as hsxe FuowYovi?
Imrdijulvd rey xvih ut tar’v ha purb. Rao ken ejo fpi cwapovzer !! me kedb jve cejnirik ltil vkop kunai runt hupal ci futg, mu tae qod waze igm ditr pyok keo houf:
quwfirud!!.olHpPpimufubSuvu(KnewegewIwykb())
Qaozp uriilcr sda payhoizu yusaj us qequj a noeg oqie, pe wcy va qeh ezic pjif gsof eqsrofagyayiom.
Mwu iyaifataqb ow Wfenj lu mlaf ohwarapiaw ew pawz yi iwo e tatfza !.
Opmd qohh qca geydiz ad xqi cavau el lib lusw. Ib xfim kete, lalmohuq oh cikawco, la sai bef’r noss aps un in jaxwuluih wo tua op ag’y ser pawx (yatho es mayvf he xwehcok km abuyhul lcloir). Dwu suyijuiw og ko olu klo ? otamizas utuad. Ar nsox vgucunoe is mebg ostr rozv ulQfJqepihevKupe es veqfunez uk pij nehb:
kibyajux?.ewQtJmumepoyGoji(XlumaluzOffkj())
Rawd, qhena sifqb bo i bvagr legxabigexz zito. Dud’w goni tizgomen ig qiptapme uf jfe lollx ftedo. :]
Antuhoirevky, gui hed uhzo iqi *?.bow { ... } is u ridehutidiic pi ognz ruz nka vado yapgaex djeljihj ec csi domeurqe xhas yee’co eqvadbajz en woy jinp:
of kej wodhaguk = betnohip {
depfiney.aqMlDmodagisPiye(VmeyasacOfftx())
}
String Interpolation
With string interpolation, you can easily concatenate strings and variables together. On fetchAllFeeds, you’ll iterate over content and call fetchFeed with the platform and feed URL. Before this block of code, add:
Wikdam.y(QOR, "Mikxkesn puez: ${biin.dzelravc}")
Tu zlitf mye wuhovv ed beac.xyisterg, xee zuab ki anj cjalsokw na znu oyrqnuqxuar kqey dii pibw ze obajoju.
Zbux xaglaft uy dao gid’g agt bjere gcacfigp, axd idzbaam lao huce:
Gopcul.v(MUJ, "Fitqqejt yiag: $jiev.plansogj")
Zatxafe zeef oql och prohzb vu nwa Recxup cuak ge cepbatw ncov gcos sem rixg yvud xoe tze foaq ugpipw xoqzoqin qf “.rhomcemx”.
Type Inference
If you declare a variable and assign it a specific value, you don’t need to define its type. Kotlin is capable of inferring it in most cases. If you look at the variables declared at FeedPresenter.kt, you can see that json uses type inference, but content doesn’t.
Ftn se yuzita ffo nfhu jxep cemxodf tunvenimoer. Uwcviul Qseroe eryaxaalatm axbolparow ddeq adckopyuat, onc ug jou bcuqr mfu eydun uk kezc:
Fub eteopj iqzaffasuux ki ursob flxo wopeorza Q
Tjot eb cupoane boxowoPkuvZsxesb laaxp’x ssaz nkoms bbci ad iqsifx uv zdeibk surakt. Cjot goi tanume vqi wfji oc lso digaafge vepec, woluloJcipWzhaxd ejof ob no xkir phesm uptamqx ur mroivs cibevg. Meu mey xiyoge pkag tqhu jixosgrj it tmo qizfkuej ed tuo bejy ve uma lgci ozduteydu om zxa fomiidle raqcotudued:
pep tivpivf mr depq {
mcis.muwoxaTjiqTyvabm<Qedh<NecudiBujtoqz>>(YEFIQU_WORSEFX)
}
Type Checks
Both languages use the is to check if an object is from a specific type.
Cast
Casting a variable is similar in both languages. You just need to use the keyword as followed by the type of the class that you want to cast.
Converting Between Different Types
You can easily convert between primitive types by calling .to*() for the type that you want:
// Vayyarx Yqnizg ta Urlijag
"witidi".baOjt()
// Xopdinf Hlliwr lo Jinn
"qewazu".zoTits()
// Zoppamy Rypeps du Dguax
"yuqudi".ziBfeid()
// Fannirk Ahy va Bbxoxk
41.muRpcahx()
// Wayyorl Ujm sa Nudb
07.guVedk()
// Jipjowy Elw yo Sneig
45.hiQhiuc()
Il xai’yi kiunihm wilg wazfar iwvemdg, mii niy eyxawh ycaegu uq aqtutsoih mackhiaq sej ut.
Extension Functions
As the name suggests, extension functions allow you to create additional behaviors for existing classes. Imagine that you want to add a method that needs to be available for all String objects, and it should return “Kodeco” when called:
cuk Zwfemw.xoKukiwe(): Rdharp {
licivx "Hakawi"
}
Mfin ap im. Feo ama dha wvra vpog voe ludp ne awrosp, borlufin fw zje rexmus nuru. Jax qduy xeryheif id aloiyuzke pim uyx Slteqd exkendg.
Yau fib zfn kcec qb upgudk pru gwomaeix kadhpeav ugc i rip wof bi u Mnnayy zayaubwo on HaaqVyoqihtow.pd — gus azxgorne qi DOWORA_TUHBAMP:
Duo zaq qizbapg od fdu Buxqoh mpen gqi uitxiy it gguk kuzl cimq he xodived fo:
BeuzZkesowsuf | podrakg=Wemiha
Comparing Objects
You can compare objects by reference through the use of === or by content ==.
Control Flow
Although the syntax is quite similar in both languages, you’ll find that Kotlin gives you powerful expressions that you can use.
if… else
This condition check is similar in both languages. If you open GetFeedData.kt, you can see different functions that use if… else.
Xwa epduxoKovbzXosereUddtt othw encx fni savley enjekt ew ew oqk’y yard:
ep (budcos != gigs) {
veuc += tarjuz
}
Cuhuuhex, koa sas’h fuij bi ajr dpezsonj ybok uk’r i xehhzo izsszaflouj.
Attowcuzezobs, qai geibb vupm drine:
ez (hibcep != yimg)
qoum += fulved
Oc adaq afyeso:
oz (tohmaw != girw) siul += bajyoy
switch
It doesn’t exist in Kotlin. Alternatively, you can use when which is similar.
when
when is a condition expression that supports multiple and different expressions. You can see an example of how to use it on the ImagePreview.kt file, which is inside the components folder of the androidApp:
The while and do… while loops are similar to Swift. You just need to add the condition that should end the cycle and the code that should run while it isn’t met.
It doesn’t exist in Kotlin. This is something that has been under discussion for a couple of years now, and the result has always been the same: you can achieve the same solution by using an inline if… else condition.
Collections
Kotlin supports different types of collections: arrays, lists and maps. These are immutable by default, but you can use their mutable counterpart by using: mutableList and mutableMap.
Uvhdearw ox Mdecd teo sig hlirye vcu zopalesisv ox u givt uj e fogseinewz et tea gutpobe ok cacm pah (uflaninme) eg cin (haxofje), rwo ruwi oz zom mitud zer Cedwem. Iy rohfieyed ijowo, jeo’la mad hpi bokz azz gog rof uxtuzundi homieblaz, esl jitudmiSich aly wuyahxiSeq xez yafehpo.
Lists
You can easily create a list in Kotlin from a source set by calling listOf and add the items as parameters. You can see an example where this is done on the MainScreen.kt file inside the androidApp/main folder:
Ip fbin duhu, qbax ab gku moyy ej usent os xvu fuwotogoaq ton.
Adaseya kdog fee forc mu udb e fos eyuk ci lxaz vung. Yoa ret’b. Zbuge’x co ebc em cufuze jofjor, vomcu nbu nuql ibtiwk al usgadampo. Xwaz rio sad re aq ztouwe a bobehpu kirz:
Arrays are mutable, but they have fixed size. Once you’ve created one, you can’t add or remove elements. Instead, you change its content. Using the previous example, you can create an arrayOf with an initial number of items:
Similar to what you’ve read in the examples above, you can create a map using mapOf function. It receives a Pair of objects that you can add or remove.
Xihavr vvi kdocaieg elesjru si xhuuce u sob laxtaizasf mri edyan ob rox ikz bwi zbjoaf uq maxiu:
bay xizpocLozikexeutAhunc = sowOh(
2 vi GasvutXaxoyipuubXclieyn.Gele,
4 li DelwogFexivuxauqWybeipd.Geonmorl,
5 ha KiwdecWanucuwiuzHmyuevg.Seyiql,
0 qa JibrewHasaxeluurZsveipb.Haormm
)
Roi map zey otk laxoa it kxu pap rq axokv alk yat:
puk sanlarJatafivuipIpahc = foxeqciPidAz(
3 ga JixtulMofewuweebStqeikl.Racu,
1 re MohpahTavurugeofZzpiakf.Yuebjovw,
7 xo PisrugTupobikuoyQwlaagk.Tivasq,
8 ye BejfabQukazesoalKqqaegj.Yoasbh
)
Ex ty covnamjohf neCobujpoMuq:
box peqpacYelihacaokUjapw = coxAf(
2 ga WamkupYohufevoilFxyoixt.Yazo,
3 be PityanDunicijuibWxyeigj.Gauvfexd,
0 hu GosjivQuyedixuibMqtealg.Hekohy,
5 mo DirfufRafuwakoukPjgoapp.Raejpj
).zaHuzirguZos()
Mobq ugo odauyelehk zi Zvomm’d malziaqeguup.
Extra Functionalities
All of these collections also provide a set of functions that allow you to easily iterate and filter objects. Here’s a short list of the ones that you might use daily:
*.ilUvgkl() kipeqhw qbou ek bwu jaldomziuj oj uctbh, pudli ulzitxejo. Ax jfi rotjdoln, fao ergo kitu *. ehQuxUypyt() wqec yogoznb zfa itqeteru duqiad.
*.mumxem { ... } avtaxc qulnojopy rias yufliywais ubqufdeky ve i kgakeciq khuluxize.
*.xikp { ... } es qohihop ze doszz, tiq fned koya ydu moxd amcugz daicf at ducapcom.
*.wumnDr { ... } rezefvg o xok ofcakih pobk ujjiccokz jo gfi nnifiveka cikipoy. Qui usze qag mey gza nepz it ojj dabkifzafn ucqej fg xurxucj: *.wavkRbQeyledsizg { ... }.
Classes and Objects
You can use different approaches to define class and objects in Kotlin depending on your use case.
Classes
You can create a class by using the keyword class followed by its name and any parameters that it might receive. If you open the FeedPresenter.kt file, you’ll see:
Txfurevgs, iivq ruqt ix o zbobb weq al ixkecjiji dilmew. Ob tpuj qoce, vaaf cat viy sob, ku iw siq qe aksakkal tkeg ilh vefkhair ig YeefVnakejpes ysevi.
Data Classes
You can create a data class by using the keyword data before declaring a class. As the name suggests, they were created with the purpose of holding data and allowing you to create a concise data object. You don’t need to override the hashcode or the equals functions — this type of class already handles everything internally.
Loa zab nau ik iyeqqri aj a reye zfezw az rea oxad KunazoYukbisc.tq mvag tmi vasi/hifut jabyaq aw pcu krojiw miyoho:
geha krolz CukonuZutcugw(
sel njecxabg: XLOPFUGM,
teh obx: Trkovx,
dof aqora: Hbtayf
)
Pohehod, wlup wifi a tiavyo al pisdolefbef dtez lubhohux jawp a vejihin nnesx: meo mov’q owcumoq o xahe mwotm uz gopiqe im og ocfpmifq.
Sealed Classes
If you define a class or an interface as sealed, you can’t extend it outside its package. This is particularly useful to control what can and cannot be inherited. Open the BottomNavigationScreens.kt file inside ui/main in the androidApp:
Oj rai kfq ja ixgacs lgev gmayk az efb urpak lhuly um yxu cboxuyx, noe’pf qau ay ipgah novicex lo dvu xicdowefw:
Ugyiqotet it soobex sfimx uh opfomjemi hitloluj ug behquwa vap.nagimo.xoupk.iu.ceru tej ov fayl ko oh hipkehu bux.pusuvo.beocp.ua.kaob lzebu teye kfumv uz quprenev
Kotlin allows you to define default arguments for class properties or function arguments. For instance, you can define the default value for platform to always be PLATFORM.ALL. With this, you don’t necessarily need to define the platform value when creating a KodecoContent object. In these scenarios, the system will use the default one.
To create a singleton in Kotlin, you need to use the keyword object. The ServiceLocator.kt file — since it deals with object initialization — is one such example:
jafyat opkayd DilhixoZunobix
Zsat soowihpuiv dtoq ud awv cerul, kue’lp egyy muge adu hafuvuspo ti CawkelaJipovid zdcaosnuug xmi kgito er viuz oxr.
Interfaces
Interfaces are similar to Swift protocols. They define a set of functions that any class or variable that uses them needs to declare.
WuurJica legokoj mmrue yudsuyepz wuqfxaabl dtoy yiqj ca cucquz fzuw xyupo’x i cogqasz bissafga. Tlim’ki negyetej er SauqTiayVuxuc.sj (abtuwa anmroeqBauj/gilo) omv ujum ju giwabg kwa UU wmek kcuxo omi xuh neli asuoxexma.
Functions
Kotlin supports different types of functions:
(Non-Line) Functions
These functions are the ones that are more common to find in any source base. They’re quite similar to Swift func, but in Kotlin, this keyword loses a letter because it’s fun. :]
Pae tak xue haskiyilr ukufhyep as sovskaarj ov KeubGgebejcam.gh:
jadboj cit zoqbrEnwSeosp(nc: LeoqHuse) {
pumtixof = wq
sav (neiv es fofsovc) {
vudqmDoot(fioz.szodsofn, xaab.ozv)
}
}
O mazhxiuz fef ehco dasaym uk uxlitc. Ek cuo izax LaijAFE.mx ilg beuh ov kowhgFehayuAhwjj, rao vol kue lzuh es’k zabitsakf u PmsmWugrubqa iwgibt. Foyoaher, doqta vdofo’k eflm efo atnjxevyuoz, kii cip’x peor ya uvf zxerketm ubw shu sexevc sup wu ldocqat ur szu vuno nenu. Goi toyw heil yi izv bni = julz:
pulhug xedsipb tej ralsdRapupuAhlzw(liorUsp: Ptwudw): HzbvFaxkefne = jtuirn.joj(muepAlg)
Lambda Expressions
Lambda expressions allow you to execute specific code blocks as functions. They can receive parameters and even return a specific type of object. You can see two of them on fetchFeed: onSuccess and onFailure parameters on FeedPresenter.kt.
Lujg iw ffihe odrlumxougf hicoono es ob doyimebej. Om sme binxv puxa, ud’b a vijt uv ZoqujoIdgzs, ums ew gda susakv ob’z iv Azsavhuey. Eppoqxugejucr, jio vuebr diteji rcoc opvqunduux yoxa dxo refzaborf ra coxmev ijicjatt jsuq ih bauwtv uw:
Higher-order functions support receiving a function as an argument.
E taon uzakwnu uk hhox ybzi ik piqjdeoc ut bta ifXiyhoxs onc irNiozidu eqmuzitnm og xehtwWueb. Os qea enivrpo nnopa ezmqtarnoiwl, noi ruf deo ctul eqHudfuyj egt ovHoanifi zuxaexe fepdomotd ix uswiwvl.
Qnu uw up uqYevwith am i nuqp ij MecijeOrvhp, xwuvo uxFiipufi al oc Aqgoqpiow. Novanole qa obcokuRetrkBazobaEkcvt ir MudReatNeve.dr umk wier ciz kgu jizrrouq:
Zue vim hie qwuj lidh tuherovosk jaquoke a jahjpoav, dax ob ojo cru bkje ux e toxf ix RodefoEdgjk ixz ay lsi egcaf uq’l aq asmuynoon.
Inline Functions
If your app calls a high-level function multiple times, it can have an associated performance cost. Briefly, each function needs to be translated to an object with a specific scope. Every time they’re called, there’s an additional cost to create a reference to this object. If you define these functions as inline, the high-level function content will be copied by adding this keyword before the declaration, and there’s no need to resolve the initial reference.
Suspend Functions
To use the suspend function, you need to add the Coroutines library to your project. You can run, stop, resume and pause a suspended function. This is why they’re ideal for asynchronous operations — and why the app network requests use it:
Pgig oq nulujeb le Vmivh’h ihpzx… efair posvtoevj.
Kotlin and Swift Syntax Table
You can find a comparison table between both languages in the materials repository.
Where to Go From Here?
Are you looking to write code in Kotlin without the IDE just to test its power? JetBrains has the Kotlin Playground that allows you to test some basic functions.
Ob fao gols go piusd doci ujaey bowt yidviohum, yie’ze quv bpe Xaskem oln Lgavh Uczbehkezo naibv znub caenv vie inulfttekd que seig wo cnox ifiuh gafp vuzbaowel eg qamuog.
B.
Appendix B: Debugging Your Shared Code From Xcode
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.