Swift Language
functies
Zoeken…
Basisgebruik
Functies kunnen zonder parameters of een retourwaarde worden gedeclareerd. De enige vereiste informatie is een naam ( hello
in dit geval).
func hello()
{
print("Hello World")
}
Roep een functie zonder parameters op door de naam te schrijven, gevolgd door een leeg paar haakjes.
hello()
//output: "Hello World"
Functies met parameters
Functies kunnen parameters aannemen, zodat hun functionaliteit kan worden gewijzigd. Parameters worden gegeven als een door komma's gescheiden lijst met hun typen en namen gedefinieerd.
func magicNumber(number1: Int)
{
print("\(number1) Is the magic number")
}
Opmerking: de syntaxis \(number1)
is basis Stringinterpolatie en wordt gebruikt om het gehele getal in de string in te voegen.
Functies met parameters worden opgeroepen door de functie op naam op te geven en een invoerwaarde op te geven van het type dat wordt gebruikt in de functieverklaring.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
Elke waarde van het type Int had kunnen worden gebruikt.
func magicNumber(number1: Int, number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
Wanneer een functie meerdere parameters gebruikt, is de naam van de eerste parameter niet vereist voor de eerste, maar staat deze op de volgende parameters.
let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"
Gebruik externe parameternamen om functieaanroepen leesbaarder te maken.
func magicNumber(one number1: Int, two number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
let ten: Int = 10
let five: Int = 5
magicNumber(one: ten, two: five)
Door de standaardwaarde in de functieverklaring in te stellen, kunt u de functie oproepen zonder invoerwaarden op te geven.
func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
print("\(number1 + number2) Is the magic number")
}
magicNumber()
//output: "15 Is the magic number"
Waarden retourneren
Functies kunnen waarden retourneren door het type na de lijst met parameters op te geven.
func findHypotenuse(a: Double, b: Double) -> Double
{
return sqrt((a * a) + (b * b))
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
Functies kunnen ook meerdere waarden retourneren met behulp van tupels.
func maths(number: Int) -> (times2: Int, times3: Int)
{
let two = number * 2
let three = number * 3
return (two, three)
}
let resultTuple = maths(5)
//resultTuple = (10, 15)
Fouten gooien
Als u wilt dat een functie fouten kan genereren, moet u het sleutelwoord throws
toevoegen na de haakjes met de argumenten:
func errorThrower()throws -> String {}
Als u een fout wilt gooien, gebruikt u het trefwoord throw
:
func errorThrower()throws -> String {
if true {
return "True"
} else {
// Throwing an error
throw Error.error
}
}
Als u een functie wilt aanroepen die een fout kan veroorzaken, moet u het sleutelwoord try
in een do
blok gebruiken:
do {
try errorThrower()
}
Voor meer informatie over Swift-fouten: fouten
methoden
Instantiemethoden zijn functies die behoren tot exemplaren van een type in Swift (een klasse , struct , opsomming of protocol ). Type methoden worden op een type zelf aangeroepen.
Instantiemethoden
Instantiemethoden worden gedefinieerd met een func
binnen de definitie van het type of in een extensie .
class Counter {
var count = 0
func increment() {
count += 1
}
}
De methode increment()
wordt aangeroepen voor een instantie van de klasse Counter
:
let counter = Counter() // create an instance of Counter class
counter.increment() // call the instance method on this instance
Type methoden
Type methoden worden gedefinieerd met de static func
sleutelwoorden. (Voor klassen definieert class func
een typemethode die kan worden vervangen door subklassen.)
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
Inout-parameters
Functies kunnen de doorgegeven parameters wijzigen als ze zijn gemarkeerd met het trefwoord inout
. Wanneer een inout
parameter wordt doorgegeven aan een functie, moet de beller een &
aan de variabele die wordt doorgegeven.
func updateFruit(fruit: inout Int) {
fruit -= 1
}
var apples = 30 // Prints "There's 30 apples"
print("There's \(apples) apples")
updateFruit(fruit: &apples)
print("There's now \(apples) apples") // Prints "There's 29 apples".
Hierdoor kan referentie-semantiek worden toegepast op typen die normaal waarde-semantiek zouden hebben.
Syntaxis van volgsluiting
Wanneer de laatste parameter van een functie een sluiting is
func loadData(id: String, completion:(result: String) -> ()) {
// ...
completion(result:"This is the result data")
}
de functie kan worden opgeroepen met behulp van de Trailing Closure Syntax
loadData("123") { result in
print(result)
}
Operators zijn functies
Operators zoals +
, -
, ??
zijn een soort functie met de naam symbolen in plaats van letters. Ze worden anders aangeroepen dan functies:
- Voorvoegsel:
- x
- Infix:
x + y
- Postfix:
x ++
U kunt meer lezen over basisoperators en geavanceerde operators in The Swift Programming Language.
Variadic Parameters
Soms is het niet mogelijk om het aantal parameters te vermelden dat een functie nodig zou kunnen hebben. Overweeg een sum
:
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
Dit werkt prima voor het vinden van de som van twee getallen, maar voor het vinden van de som van drie moeten we een andere functie schrijven:
func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
return a + b + c
}
en een met vier parameters zou een andere nodig hebben, enzovoort. Swift maakt het mogelijk om een functie met een variabel aantal parameters te definiëren met behulp van een reeks van drie periodes: ...
Bijvoorbeeld,
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, combine: +)
}
Merk op hoe de parameter numbers
, die variadisch is, wordt samengevoegd tot een enkele Array
van het type [Int]
. Dit geldt in het algemeen, variadische parameters van het type T...
zijn toegankelijk als een [T]
.
Deze functie kan nu zo worden genoemd:
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
Een variadische parameter in Swift hoeft niet aan het einde van de parameterlijst te komen, maar er kan er slechts één in elke functiesignatuur zijn.
Soms is het handig om een minimale grootte aan het aantal parameters toe te voegen. Het is bijvoorbeeld niet echt logisch om de sum
van geen waarden te nemen. Een eenvoudige manier om dit af te dwingen is door enkele niet-variadische vereiste parameters te plaatsen en daarna de variadische parameter toe te voegen. Om ervoor te zorgen dat sum
alleen met ten minste twee parameters kan worden opgeroepen, kunnen we schrijven
func sum(_ n1: Int, _ n2: Int, _ numbers: Int...) -> Int {
return numbers.reduce(n1 + n2, combine: +)
}
sum(1, 2) // ok
sum(3, 4, 5, 6, 7) // ok
sum(1) // not ok
sum() // not ok
subscripts
Klassen, structuren en opsommingen kunnen subscripts definiëren. Dit zijn snelkoppelingen voor toegang tot de lidelementen van een verzameling, lijst of reeks.
Voorbeeld
struct DaysOfWeek {
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
subscript(index: Int) -> String {
get {
return days[index]
}
set {
days[index] = newValue
}
}
}
Subscript gebruik
var week = DaysOfWeek()
//you access an element of an array at index by array[index].
debugPrint(week[1])
debugPrint(week[0])
week[0] = "Sunday"
debugPrint(week[0])
Subscripts Opties:
Subscripties kunnen een willekeurig aantal invoerparameters bevatten en deze invoerparameters kunnen van elk type zijn. Subscripties kunnen ook elk type retourneren. Subscripts kunnen variabele parameters en variadische parameters gebruiken, maar kunnen geen in-out parameters gebruiken of standaard parameterwaarden bieden.
Voorbeeld:
struct Food {
enum MealTime {
case Breakfast, Lunch, Dinner
}
var meals: [MealTime: String] = [:]
subscript (type: MealTime) -> String? {
get {
return meals[type]
}
set {
meals[type] = newValue
}
}
}
Gebruik
var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"
debugPrint("I had \(diet[.Breakfast]) for breakfast")
Functies met sluitingen
Het gebruik van functies die afsluitingen accepteren en uitvoeren, kan zeer nuttig zijn voor het verzenden van een codeblok dat elders moet worden uitgevoerd. We kunnen beginnen door onze functie een optionele afsluiting in te laten nemen die (in dit geval) Void
zal retourneren.
func closedFunc(block: (()->Void)? = nil) {
print("Just beginning")
if let block = block {
block()
}
}
Nu onze functie is gedefinieerd, laten we deze noemen en een code invoeren:
closedFunc() { Void in
print("Over already")
}
Door een afsluitende afsluiting te gebruiken met onze functieaanroep, kunnen we code (in dit geval print
) doorgeven die op een bepaald punt binnen onze functie closedFunc()
moet worden uitgevoerd.
Het logboek moet afdrukken:
Net begonnen
Al voorbij
Een meer specifiek gebruik hiervan zou de uitvoering van code tussen twee klassen kunnen omvatten:
class ViewController: UIViewController {
override func viewDidLoad() {
let _ = A.init(){Void in self.action(2)}
}
func action(i: Int) {
print(i)
}
}
class A: NSObject {
var closure : ()?
init(closure: (()->Void)? = nil) {
// Notice how this is executed before the closure
print("1")
// Make sure closure isn't nil
self.closure = closure?()
}
}
Het logboek moet afdrukken:
1
2
Passerende en terugkerende functies
De volgende functie retourneert een andere functie als resultaat die later kan worden toegewezen aan een variabele en kan worden aangeroepen:
func jediTrainer () -> ((String, Int) -> String) {
func train(name: String, times: Int) -> (String) {
return "\(name) has been trained in the Force \(times) times"
}
return train
}
let train = jediTrainer()
train("Obi Wan", 3)
Functietypen
Elke functie heeft zijn eigen functietype, bestaande uit de parametertypen en het retourtype van de functie zelf. Bijvoorbeeld de volgende functie:
func sum(x: Int, y: Int) -> (result: Int) { return x + y }
heeft een functietype van:
(Int, Int) -> (Int)
Functietypen kunnen dus worden gebruikt als parametertypen of als retourtypen voor nestfuncties.