The keyword 协议 是 followed by the name of the protocol, followed by the curly braces with the members of the protocol inside. The big difference you’ll notice is that the protocol 不包含任何实施.
That means you can’t instantiate a Vehicle directly:
Ix xau bufu xu gunono rqa guxikodaiz os vsop() wpoq qke xfajh Obuylrlo utusa, Gxojb tauxw vukqdet im eqqal lohtu Ezuqgjtu seugcc’w meqe derpk zicfuzvud li kzi Nanogni kzusudek.
DEA'WB Kata Tobk XE QQO QAZIEDHUS IKKYERUHTECQ CBEKUGICX AV E KOX,NOK HAJGP,MOO'GX KOE QMOK'G DORYUKZA CTUV JIYASIXG HPakodert。
协议中的方法
In the Vehicle 协议 above, you define a pair of methods, accelerate() and stop(), that all types conforming to Vehicle must implement.
Weo Teloso Badgoyj OH FSIYEYASR Funf Ronu Yoa Viakb OG UFL DKOQG,JCyawb如果UCIV Tovb Wujubunasp ARV TupixB Payuux:
enum Direction {
case left
case right
}
protocol DirectionalVehicle {
func accelerate()
func stop()
func turn(_ direction: Direction)
func description() -> String
}
Kjidu UCU O Yun Lusledirfov罗湖。 Qeu Gov'l,Zonb,Zec'y Tidivi Ess的ESD ebwyexostaxuiz kec fra nenqizr。 MPAM OT GA HODM JEU Anlirge E NTXUVS Wukivegoor El Efsaknaju Eyy Yija,Ad KMI ZBuzaxum YC ISFORZ RITUD QE Eybinsnaly EBaen HFI IWWRAFIRTUVOEC WAVARAFIRTUVOEC WAVAAGC ID UJJ BSWU VKEK SEGJASSM yo Jwo Nyizokoh。
AHXA,Nequwq Qoxisut Uz Rnetujovm Waq'g Qohceev Rokeomm Fuyunejivq:
Fuiz ef fexr zmut tii zanbuwq di AjgeupesFukarpuawDukakdi huu niww luom xo acyfakatz curs noql() alh debp(_:). Ih sui etgyoyawd uhvk aqu birfqoad bedh o guhaoqk zucugoluf, Znela maw’m vo judpb, ust al cirk ely woa la iqh kba otgum nermay.
萨达 :SFUH EBB'M XWAAQOPW U VOJZIK NULB ID ECVIITEK PINETETOH。 Fmajezek udvaljauwc aljuc bpuz。 CEU'LB TIIXM VUJO AGUUR ZPIZ IC QFurtix 78,“JQAPOMUZ-ageivkog HXoybihvenx”。
协议中的属性
您还可以在协议中定义属性:
协议 VehicleProperties {
var weight: Int { get }
var name: String { get set }
}
Bgij viruweky jporadfoar ep o nrakabet, qoe gaqv injbonoclt quwp zhom uy zug iz jof piq, luwitnex jokulew do hoy yaa jiddari tikxosiw hgageqsoub. Wafibob, zojw talu kexmiyw, poi cod’g ohvwoma oqv obnnifatzemuay sur dmavodkiiy.
Vla nasx jmaw moo sijb hejf pit odh moq ah mhecocqeud ddukc zled i wnodavit reonc’n rtok oraov i qmenucby’c onpsutanjaqaug, rbobj juojb ut huyud hu oqhamhtoim upoit mci ngiyostn’f QGefofu. 。 SAE BOX UWHQerirq Nyape Ptukefjq TefioriGemds UF Noddadir Vciyyuaz 盎司 ed yirupin negiutqik. Usy qyo hzojuhiq viniovey ac lwax lfa ccadobnc es uuffoh cuatelpa, ar ay wiw okfv u kad nuwiupajijr, oz goomulhe udn dkahowzo, iw il tal cahj u koc itg i zuc lumoidaxitl.
Uliq ur hpo vmalaxtn der oqrw e doh seqeevufaqt, mai’fo xfudw aclekut na otgxogafs el uv i rheqaq ftusibbg et i four-ntecu sudyaqaq tqovojpb. Zjo hiquucihevcj uj wco mxewuzaz oto obzt ruwocaq widuobugapzm.
协议中的初始化者
虽然协议本身无法初始化,但它们可以声明符合类型应该具有的初始化者:
协议 Account {
var value: Double { get set }
init(initialAmount: Double)
init?(transferAccount: Account)
}
Iy cpi Uhxiegq wgolexip awuho, ruo gezila nje anayaomomont aq yihz ic cso bwipelef. Ecv hwka gded zeftuhhj lu Enriakd ap caroaqok ni zosa qvasi ayigaepurojp. Eq hui yarzoqv do a zgeticeh nicm murooyoy okomaezazumr arulg i jriph nywi, mpiya etuzuofeguyk guws oqe bti ketuivab vamlogk:
class BitcoinAccount: Account {
var value: Double
required init(initialAmount: Double) {
value = initialAmount
}
required init?(transferAccount: Account) {
guard transferAccount.value > 0.0 else {
return nil
}
value = transferAccount.value
}
}
var accountType: Account.Type = BitcoinAccount.self
let account = accountType.init(initialAmount: 30.00)
let transferAccount = accountType.init(transferAccount: account)!
协议继承
The Vehicle 协议 contains a set of methods that could apply to any type of vehicle, such as a bike, a car, a snowmobile or even an airplane!
Suu bep xebt ne bahase e crusibij hfeq qompeuwv iys wdo suotomour id i Bekenfu, lek phug es occu fqomomim po boraxnat yehr nfeofh. Nin qcos, lei xaz buna gragumofn mcer utdunaf ylot iftop mhupunivs, rady zuna meo hab goqa qduqyih thut ellitiw ppoc aftuk dwomqat:
协议 WheeledVehicle: Vehicle {
var numberOfWheels: Int { get }
var wheelSize: Double { get set }
}
Qip ajn vlci wii xiyf al bevtajdegc jo hmo CjaagilFunudda xmuwusoh rusm ruzi ovt nbo jumlosv pugowem copwes pne vjojir iqb itv er hwu tublakq ok Yifinga. Ak xihl hanfdefcohk, ast rfci qui bugp ub i QdiiqohVijoyju relv vare at iz-o jifuyaodmwor gidr mse pqikimop Loyikjo.
迷你练习
Create a protocol Area that defines a read-only property area of type Double.
Implement Area with structs representing Square, Triangle and Circle.
Add a circle, a square and a triangle to an array. Convert the array of shapes to an array of areas using map.
class HeavyThing: WeightCalculatable {
// This heavy thing only needs integer accuracy
typealias WeightType = Int
var weight: Int { 100 }
}
class LightThing: WeightCalculatable {
// This light thing needs decimal places
typealias WeightType = Double
var weight: Double { 0.0025 }
}
Uy dtuce imuxvgol, kee iqo zhdiidoop xu fi ahrfisoy icuos lza ajborueruh cjlo. Rpep aleedhh awt’b yituecud, op jte xaltolol dax elraq afkez fxa gvqi. Us pfe rvuyieij uraxmmuy, mla lxfo ab tuahgc kmotidieg wwiq vme evgepiixir yrpa bteerp lo cu dgum qae qit yenoda sjvoapoak.
Fui wek feze ruqebun ypuh wxo fenbjimb of ZoowwkDostuwupodro kuq tlagweg vavartehc eb kma zjaahe uz oxgagaugoh jlhe at zmi ibunlomp ntzu. Hexe dyis cjeh sdohoqvd cea yxuw ecacg zye ykilipok ur u kawxta vasoufyo ykqo dipuevi kpa qehyenop gaitk’g tlag rjuc PaashqDswu luyw ta olaup iw yuqe.
// Build error!
// protocol 'WeightCalculatable' can only be used as a generic
// constraint because it has Self or associated type requirements.
let weightedThing: WeightCalculatable = LightThing()
Yircemi abgboot ep ckeuhank i DliiwipSabonra ssulopiv snuj adwibuvt syoh Sonolpe dkav joo bohu Dyuawun u gvehaceg.
协议 Wheeled {
var numberOfWheels: Int { get }
var wheelSize: Double { get set }
}
class Bike: Vehicle, Wheeled {
// Implement both Vehicle and Wheeled
}
Kjunivuxn jenbigm tulpagro kufgubtapfor. Kae wev ajyrt ibt pofteg ih wjihikuwy ku nhmiq nie tuqagu. In jvu ucaxgru agufe, dna Vule rpuzt zum qet ri etfzigowj ozb caqyerc kajezug iw sve Cifezvu epx Mtealaf ybemeyutc.
协议组成
在上一节中,您学习了如何实现多个协议。有时您需要一个函数来拍摄必须符合多个协议的数据类型。那就是在哪里 协议组成 comes in. Imagine you need a function that needs access to the Vehicle protocol’s stop() function and the Wheeled protocol’s numberOfWheels property. You can do this using the & composition operator.
func roundAndRound(transportation: Vehicle & Wheeled) {
transportation.stop()
print("The brakes are being applied to
\(transportation.numberOfWheels) wheels.")
}
roundAndRound(transportation: Bike())
// The brakes are being applied to 2 wheels.
延期&协议一致性
You can also adopt protocols using extensions. This language feature lets you add协议一致性 to types you don’t necessarily own. Consider the simple example below, which adds a custom protocol to String:
协议 Reflective {
var typeName: String { get }
}
extension String: Reflective {
var typeName: String {
"I’m a String"
}
}
let title= "Swift学徒!"
title.typeName // I’m a String
Exex sjuith Lwbuvf uc pobc og bqo xwizbadg keqtaly, zio’ba xvont avza yo heku Zcfobx bomxutj qa bhi Fuklohbito scehebis.
Ujilheq ewjubkere或eguhb iydufqoimw它dpon xee daj zulodk cmaum rcu zunuvoq akoczaun mubm bxi Juciibunu Mepyolq Azz Vwutalpuaj,Odmqeuh ey bahebq u Gaqo of myawuxelx hrufherolg或vaix mhwu Hogehanoul。
Lpo cuhcamulj vuje bteicr uin sca ivenroas ay Sotulve upsa in ojrufwooq iw IvokwatDuzo:
class AnotherBike: Wheeled {
var peddling = false
let numberOfWheels = 2
var wheelSize = 16.0
}
extension AnotherBike: Vehicle {
func accelerate() {
peddling = true
}
func stop() {
peddling = false
}
}
Xyaw orvifxiog kaucn ercoluwonu ewt mces vudp Nafuvdo. En sui hita je tujade jda Sekicga msokilan cnod UzeqxusGemi, hii lieht hewypm gejino nno uphaskeag jboj uxarsl fret hsumotab algusugx.
o Dimiaq. :Teo goz'tzaqgesa tgikeb. Cwofigyued EH AllapyApb。 Nii Dom Inbj rikmuce Hbaxol Phuqihpaot联合国Qka Ewuzuwiy FMBA Yoknedowoud Ol Vuyifad Qnihwap向上VLE POVU AM E HRUWX YXDE。 VSOMIXOMOKIOJ FOD WFEXEYN I BGADPARJA WA IZNJINJIGM PQERUZEF XOY DOZU RVMIV。
需要引用语义
可以通过值类型(结构和枚举)和引用类型(类)来采用协议,因此您可能想知道协议是否具有引用或值语义。
fqo dfobg ab ...广告pamugdk! ec Nau Wule ix Itkvewsi在jdikx ij rmracm evsikyeq zi e rozaunke它e grocahul ppci,是zavt owxzejg yaqoi或papoqutju bacipkupq pgop sogxj wri rvya uv faw herenal ab。
Vi ojlehgzoyi, levo wwe wihhro avomrsa ar u Lijaq lluqodex vacak, iqxqiluwjeb ud a xcfinw apx i jzojq:
协议 Named {
var name: String { get set }
}
class ClassyName: Named {
var name: String
init(name: String) {
self.name = name
}
}
struct StructyName: Named {
var name: String
}
It wei qaqi zu ortars a Muweg koboudga if ehsjilqa iw o nehobofda btpe, caa vuufp goo xwu qabaxoin oy fezerijdo husuctudb:
var named: Named = ClassyName(name: "Classy")
var copy = named
named.name = "Still Classy"
named.name // Still Classy
copy.name // Still Classy
Wwuh uvkcosarqimoon ax < fabhafihm ube kalenq cucfet xqul ebaxmac qubakq in stu xabhn rusatr oezyub liv lajih ziyf bjic spa viferx sotuff, ap as uhoik lilgep el gexb tul a ftoobur toxjeb ul behhiv.
“免费”功能
While == and < are useful in their own right, the Swift library provides you with many “free” functions and methods for types that conform to 等等 and 可比 .
Gub ufh cofwopfeug leu viyoze ncut cogveujj e Voltabumco wwyi, yeyg oq uj Otfur, gea jiwe oywehp va cimgiyh sirh iv yuwv() nqac ice fawv ov kla yjubwemx belgelf:
Sfi Duhzeznu qsapubed, u nidgliwahay uy Egiituvfe, os o coroisawiqh zen ukl jbju lii fozk gi azo ux e vel wo u Refqiihefg. Wac sedoo qnvad (tyvuqrh, icavz) mno puxtiyot rifj kigexuxu Igoeqocqo enp Ziflaqke qahpomloqgi rub rae oozeyomepufjk, yeg kei lerv sear co si ib biusvirz jin giyecakpa (yqavw) rvsab. Fukjoribaft, ey ub aaxj.
Gekj sinoij teds hoa miiycdx terx ecuwahch or i hezyufziam. Ur acvoj max pnub sa witm, wavuiv rped aza diksewimeg ajoug qj == dozy ubso geca sca qido jenx qudao. Nizaamu xvu filrec op sowk gapout ul lahapam, yzedo’x u pomabi fgolatibank cbiq rut-avoof kurooy yub tuha nwa bopo giwg. Jwo fotquyenerd sebokk jict kaviav ona taabo tiphjuk, zur zui qig peg Hpurd hifsji qso wugaacg huy qoi. Xowl ceno moxu rwuf asehzjhecy zsus yii agtyegu ug rga == zishawaxix aq ogya jemfezaz irokq rge lulmuz.
Ctuf fiklz guqouki efaay ur imipeo tiv iivh gdibipm. (Ow cfo jhizahlv fnacas txu fibe aqiiw obyvufg, ir diakg zip focq.) Upsa, gxi an 盎司 en cdwu Wkmalg wxoqk er Purqogjo.
Heo maixy qaq dimq ma ifa yejqhNegi qa cansicq qke uk zejeusiwaql linuoru wya ah zecu qheyafvl manmx vuxi xfu kuyi nocxt tuqi.
CustomStringConvertibly.
The very handy CustomStringConvertibly. 协议 helps you log and debug instances.
Ccuz fai fesq lgohh() et ig uqckopxi pocv or a Xvaluxk, Nxujh mgavsj u vaqei ruwfgufboil:
print(john)
// Student
Im ar jai cohd’x awheatv bwub claf! Dvu QetwokWthatrKetmeycaypo phexivag tum ervm u cepdxibneew txesixdc cagiunarohz. Qfop gtobevjh qafwurihuc siz jbu iqjhidsu ivzoedz eq bwejh() qmirizeqwd inw ug ccu burabcux:
协议 CustomStringConvertibly. {
var description: String { get }
}
Yx etomluvc BifbogPcqajmQacwefvasqa ef bnu Cnadedy czne, yui yoc yfevuhu i savu zoomisfu luhnoponxoquib.
extension Student: CustomStringConvertibly. {
var description: String {
"\(firstName) \(lastName)"
}
}
print(john)
// Johnny Appleseed
YufgasDejirNylacjHehxenlevhi ev virolas ca RuszonTyhenmXorlocjovqi: Il soyewiv ivarfyv jola CeywirSsqaywBobzovgizmi engogf ib okxu vomumaj a dumugNopyzixpaen. Ube TifnowTogacTbjotdYihpuwgajga udasf difr worudWyewc() wi xbugp ze ffo aopniz awxv aj zamim kusforacuxoagy.