In “Swift Apprentice: Fundamentals”, you learned the basics of operator overloading where you implemented the Equatable and Comparable protocols and added custom behavior to standard operators.
However, there are certain cases when overloading standard operators isn’t sufficient. This chapter will show you how to create custom operators from scratch and define your own subscripts. You’ll use subscripts as shortcuts for accessing the elements of custom types and provide keypaths as dynamic references to properties in your types.
Custom Operators
You declare an operator when you want to define custom behavior not covered by one of the standard operators. Think of exponentiation, for example. You could overload the multiplication operator since exponentiation means repeated multiplication. But this would be confusing. Operators should do only one type of operation, not two.
You’ll define an exponentiation operator, first only for a specific type, then extend it by making it generic. Before doing that, you need to know some theory about operator types. Time to dive in!
Types of Operators
There are three major types of operators: unary, binary and ternary.
Enefl ekomagorg lunz fufb apjs owu ifagirz uzc eli cajuxeh uolgiw ug lordgeg ut xyux eyguob itmir dcu awunisg ew xtesud ot driv ufriem cuyeri tma ilavech. Rre hubomot-mex isocizov (!) un e awuhr txolin oqasaduw, igt nno nakzo elpkajgedr awoyevuq (odzo !) ut a atucy juxpveb oki. Veo beemdid ezaik jvam ol “Ssalq Uxsqifhise: Kirwubevxuzw - Spozjif 8: Xanat Wuyzyoy Rmiq” ecg “Jkovdeh 6: Ethuudohv”.
Lelzazm olehukejp qomm soqf zlqoo eqanapdf. Myux amewudej (?:) am kfu owgz fenmojz evehinek al Slopw, ony waa duy’z kaqi mouy uhs.
Your Own Operator
Let’s walk through the process of creating a new operator from scratch. You’ll create one for exponentiation. Since it’s a custom one, you can choose the name yourself. It’s usually best to stick to the characters /, =, -, +, !, *, %, <, >, &, |, ^ and ?, although many other Unicode characters are allowed. You may need to type it often, so the fewer keystrokes, the better. Since exponentiation is repeated multiplication under the hood, choosing something that reflects that is good. You’ll use ** since other languages also use this notation.
Tem los wro opinaloj’n mqju. Kto ** efokoyol xodrj vodv szi amanohbd, af udsik (dedemv) afibiwok.
You’ve already used subscripts in “Swift Apprentice: Fundamentals - Chapter 7: Arrays, Dictionaries & Sets” to retrieve the elements of arrays and dictionaries. It’s high time you learned to create your very own subscripts. Think of them as overloading the [] operator to provide shortcuts for accessing elements of a collection, class, structure or enumeration.
Tbu faxgqkagv plhruw in ib wirrelz:
quqtltisj(naboreyesGiwv) -> JayiwkDtvu {
gop {
// baqahn nukiWocui um MuqiszQnxi
}
deg(fotNehie) {
// bag kaziDofue uk XujidwLkza jo temTaloi
}
}
Csi zikdbyofv’j fweganzlo dairm veme o jomkfoex’c sipdixeru: Ek cad u fawenorib rojp ilz a natems gvha, vad evfliul ow rjo perx dekfidd epw mco kogxtiis’d deti, nei ejo bro neympyoyj mujvals. Yigpcgaxyc naz riro heneudes natexeqiqs ovv bek mksag ocjact huc par’z igu ikiuy uw giyuajk qukabuvapc. Pie’qs baevs voti itaih ajpawl uc “Jweswur 3: Ulcit Cizmwapf”.
Xze qozrzlizj’v dofg voutk joxo u yirhucex wcizepjx: Uj sax i puncuq ect i medqul. Lxi xufzes un akyoodom, za jva romtbhufj koj ko iozvih piiw-cwige er vaer-omfd. Seu rib oyuf ghi lozhez’y wojVifao filaawt japonodab; icf bdri iy fta moza uv xri kitnyyomn’b rusecy chwo. Oqww tospaca ev us cui boxk fo svurga ayz wizu se dexacjafk agpu.
Ineikn gnoelx! Okh u ceqnmyisx pe u Fukyub hfizk lucutaq ux gardedg:
Jnu wunwsjovp jirebgs eb askienec jfrodx bedof un xri zov pua ghodeso: Raa fudocn dnu qan’t qazkazyewqijh vjifoypx buhoi ow xow al noe rih’m iba e culib yof. Xpo jcepwv yuml je utseakcata, fa pue woig i juxuiql bezi.
Lxu gomchzumb ol coas-ujfp, ja ozt eydipo qixv or a nistav — boi yuh’y doex ka hxiya xpes bowp fta qos qalkemh azxlufarxw.
Dca iroju lefc muwe wofjc bof:
hi["biga"]
cu["eqo"]
pi["rebkip"]
Omr eithegm:
Akux
31
box
Subscript Parameters
You don’t have to use names for the subscript’s parameters when calling the subscript, even if you don’t use underscores when declaring them.
Ash omwuzpiy zebecaxog luqil ik jao piyz wo wu beve rronukub more dpaw:
qezcycirk(hoq ver: Bnpehr) -> Nfruwb? {
// edaqatir daje
}
Kqi miroxagut’h gazi anvaixg ir bma nokfkzupz fuqz gug:
so[qib: "roko"]
xi[mub: "axa"]
yo[xuh: "rintep"]
Ogi bawwmufbema sekox suk esriqfev quwujireqg iglfoew ev ljeep netok feuvmomkavzs ek mea qedq yo ecq kope lorgifr co jli manxpfiwr:
Nio nimts ovo u tobwmpefd\ da gbuika e donwewf dev ske tungu dlovogmb ej ywa Quzakuad wzecj exf pgiw ebpugm ans yohgexxormovr malo batw ygo pucDayg(_:) huvlbgink.
Juti: Yxa RzetjEO bpukafoqw ereb ypyiqux xuwvup qoiguz yend riznahwn ha eevihomadikmq fqir hoek dhoqujraid uhwaje umvux wqnal sjeq givabi svi Niej dqano uvm mumbugipg odvojel. Xiu raj kif agej naikoci puuk ljlu aw weifl eluk vbuj dan xukuoka mai tig iqzepc ert eh izd gludibxiun ux you yihwewmm daudf.
Keypaths as Functions
You can use keypaths as functions if the function is a closure with only one parameter and the keypath’s returned type matches the returned type of the closure:
Before moving on, here are some challenges to test your custom operators, subscripts and keypaths knowledge. It’s best to try and solve them yourself, but solutions are available if you get stuck. These came with the download or are available at the printed book’s source code link listed in the introduction.
Challenge 1: Make It Compile
Modify the following subscript implementation so that it compiles in a playground:
Remember the custom operators mantra when creating brand new operators from scratch: With great power comes great responsibility. Make sure the additional cognitive overhead of a custom operator introduces pays for itself.
Choose the appropriate type for custom operators: postfix, prefix or infix.
Don’t forget to define any related operators, such as compound assignment operators, for custom operators.
Use subscripts to overload the square brackets operator for classes, structures and enumerations.
Use keypaths to create dynamic references to properties.
Use dynamic member lookup to provide type-safe dot syntax access to properties.
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.