Alapértelmezett paraméterértékeket egy függvény bármelyik paraméteréhez megadhatsz úgy, hogy a paraméterlistában a paraméter típusjelölése után értéket rendelsz a paraméterhez. Ha megadtál egy alapértelmezett paraméterértéket, a függvény hívója elhagyhatja ezt a paramétert a híváskor, és helyette az alapértelmezett érték használatos.
func greeting(name: String = "guest", duration: Int = 2) -> String {
"Welcome, \(name). Enjoy your \(duration) night stay."
}
greeting(name: "Bobo", duration: 7)
// Returns "Welcome, Bobo. Enjoy your 7 night stay."
greeting(duration: 3)
// Returns "Welcome, guest. Enjoy your 3 night stay."
greeting(name: "Wynona")
// Returns "Welcome, Wynona. Enjoy your 2 night stay."
greeting()
// Returns "Welcome, guest. Enjoy your 2 night stay."
A variadikus paraméterek lehetővé teszik, hogy egy függvény egyetlen paraméterébe nulla vagy több megadott típusú értéket fogadjon el.
A variadikus paramétert úgy definiálod, hogy a paraméter típusjelölése után három pontot (...) írsz.
A függvény törzsén belül a Swift ezeket az értékeket a megadott típusú tömbként teszi elérhetővé:
import Foundation
func geometricMean(_ numbers: Double...) -> Double {
var total = 1.0
for number in numbers {
total *= number
}
return pow(total, 1.0 / Double(numbers.count))
}
let result = geometricMean(1, 2, 3, 4, 5)
// result is 2.605171084697352
Ha egy függvényben a variadikus paraméter után további paraméterek következnek, akkor a variadikus paramétert követő első paraméterhez kötelező explicit argumentumcímkét adni, hogy a Swift tudja, hol ér véget a variadikus argumentumlista.
Egy függvény törzsén belül a paramétereket konstansként, nem változóként kezeli a nyelv; ha megpróbálod módosítani egy paraméter értékét, az fordítási idejű hibát okoz. Ha egy függvény módosítani szeretné egy paraméter értékét, in-out paramétert kell használnia, hogy ezt a módosíthatóságot egyértelművé tegye.
Az in-out paraméterek használatához a programozónak három dologra kell ügyelnie:
inout kulcsszót a paraméter típusjelölésében a : és a típusnév közé írjuk.&-t kell írni, ami kifejezetten jelzi, hogy módosítható.Ha ezt megtetted, a függvény belső másolatot készít az in-out paraméterről, a függvény törzsében leírtak szerint módosítja, majd amikor visszatér, a módosított értéket visszamásolja a hívótól kapott változóba.
func updateVersion(_ record: inout (version: Int, title: String)) {
record.version += 1
}
var dbRecord = (version: 2, title: "Exercism")
updateVersion(&dbRecord)
// dbRecord is now (3, "Exercism")
Van néhány további szabály, amit érdemes szem előtt tartanod az in-out paraméterekkel kapcsolatban.
1. Az in-out paramétereket használó függvényen belül nem hivatkozhatsz arra a változóra, amelyet in-out paraméterként adtál át.
2. Ugyanaz a változó nem adható át több in-out paraméterként ugyanabban a függvényben.
Például az `inoutFunc(&mutVar, &mutVar)` hívás fordítóhibát vált ki.
A Swiftben függvényeket más függvényeken belül is definiálhatsz. Ezeket egymásba ágyazott függvényeknek nevezzük.
Az egymásba ágyazott függvényeket gyakran olyan privát segédfüggvényekként használjuk, amelyek meghatározott feladatokat látnak el a befoglaló függvény számára anélkül, hogy telezsúfolnák a külső scope-ot:
func makeNumber(_ number: Int) -> Int {
func double(_ x: Int) -> Int {
x * 2
}
func increment(_ x: Int) -> Int {
x + 1
}
return number.isMultiple(of: 2) ? increment(double(number)) : double(number)
}
print(makeNumber(3)) // Prints 6
print(makeNumber(4)) // Prints 9
Az egymásba ágyazott függvények úgy viselkednek, mint a szokásos függvények, de láthatóságuk a befoglaló függvény törzsére korlátozódik.
Ebben a feladatban még egy kis kódot írsz majd, hogy segíts magadnak megfőzni a remek lasagnét a kedvenc szakácskönyvedből.
Öt részfeladat vár rád, mindegyik a lasagne elkészítési idejéhez kapcsolódik.
Szeretnél írni egy továbbfejlesztett remainingMinutesInOven függvényt, amely paraméterként megkapja, hány perc telt el azóta, hogy a lasagne a sütőbe került, és visszaadja, hány percet kell még a sütőben maradnia, az előző részfeladatban megadott, percben kifejezett várt sütési idő alapján.
Korábban egy expectedMinutesInOven nevű konstans értékre támaszkodtál, amely a remainingMinutesInOven függvényen kívülről származott.
Ez egy kicsit zsúfoltnak tűnt a számodra, ráadásul nem is volt elég rugalmas, mivel nem teszi lehetővé a várt sütési idő megváltoztatását.
Hogy rendet tegyél, definiáld a remainingMinutesInOven függvényt, amely paraméterként megkapja, hány perc telt el azóta, hogy a lasagne a sütőben van, valamint egy expectedMinutesInOven paramétert, amelynek alapértelmezett értéke 40.
A függvényed adja vissza, hány percet kell még a lasagnének a sütőben maradnia, az előző részfeladatban megadott, percben kifejezett várt sütési idő alapján.
remainingMinutesInOven(elapsedMinutes: 30)
// Returns 10
remainingMinutesInOven(elapsedMinutes: 30, expectedMinutesInOven: 75)
// Returns 45
Korábban írtál egy preparationTimeInMinutes függvényt, amely paraméterként megkapja a lasagnéhoz adott rétegek számát, és visszaadja, hány percet töltöttél a lasagne előkészítésével, feltételezve, hogy minden réteg 2 percet vesz igénybe.
Ez a függvény azonban nem igazán nyerte el a tetszésedet, mert magadnak kell megszámolnod a lasagnében lévő rétegeket, mielőtt meghívnád, és kinek van erre ideje?
Hogy megkönnyítsd a dolgodat, írj egy preparationTimeInMinutes függvényt, amely egy variadikus String paramétert kap, a layers-t, amelyben felsorolod a lasagne különböző rétegeit.
A függvény ezután megszámolja a lasagnében lévő rétegeket, és visszaadja a szükséges előkészítési időt.
preparationTimeInMinutes(layers: "sauce", "noodles")
// Returns 4
preparationTimeInMinutes(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns 24
Mielőtt elkezdenéd összeállítani a lasagnét, szeretnél megbizonyosodni arról, hogy van elég szószod és tésztád az álmaid lasagnéjához. A lasagnéd minden tésztarétegéhez 3 tésztalapra lesz szükséged. A lasagnéd minden szószrétegéhez 0,2 liter szószra lesz szükséged.
Definiáld a quantities függvényt, amely egy variadikus String paramétert kap, a layers-t, amelyben felsorolod a lasagne különböző rétegeit.
A függvény ezután meghatározza a fogáshoz szükséges tészta és szósz mennyiségét. Az eredményt egy (noodles: Int, sauce: Double) típusú tuple-ban kell visszaadni.
quantities(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns (noodles: 9, sauce: 0.8)
quantities(layers: "sauce", "noodles", "sauce", "noodles", "meat", "noodles", "mozzarella")
// Returns (noodles: 9, sauce: 0.4)
Sajnos a kéznél lévő szósz térfogata folyadékunciában van megadva, nem literben.
Hogy segítsen eldönteni, van-e elég szósz a kezed ügyében, írj egy toOz függvényt, amely egy in-out tuple paramétert, (noodles: Int, sauce: Double)-t kap, és átváltja a szósz mennyiségét folyadékunciára.
Ne feledd, hogy egy literben 33,814 folyadékuncia van.
var amount = (noodles: 9, sauce: 0.8)
toOz(&amount)
amount
// Returns (noodles: 9, sauce: 27.0512)
Végül szeretnéd tudni, milyen bort szolgálj fel a lasagnéd mellé.
Azt hallottad, hogy fehérbort kell felszolgálni, ha több mozzarella, ricotta és béchamel van a lasagnében, mint hús és szósz, egyébként pedig vörösbort.
Írj egy redWine függvényt, amely egy variadikus String paramétert kap, a layers-t, amelyben felsorolod a lasagne különböző rétegeit.
A függvény öt egymásba ágyazott függvényt használ, hogy meghatározza a mozzarella-, ricotta-, béchamel-, szósz- és húsrétegek számát a lasagnében, majd összehasonlítja a rétegek számát, hogy eldöntse, felszolgáljunk-e vörösbort; ha igen, true-t ad vissza, ha nem, false-t.
redWine(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns true
redWine(layers: "sauce", "noodles", "béchamel", "meat", "mozzarella", "noodles", "ricotta", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns false
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Swift nyelvet 35 fogalom116 feladat segítségével, valódi emberi mentorálással, mindez ingyen.