Swift Language
Funktionen
Suche…
Grundlegende Verwendung
Funktionen können ohne Parameter oder Rückgabewert deklariert werden. Die einzig erforderliche Information ist ein Name ( hello
in diesem Fall).
func hello()
{
print("Hello World")
}
Rufen Sie eine Funktion ohne Parameter auf, indem Sie ihren Namen gefolgt von einer leeren Klammer schreiben.
hello()
//output: "Hello World"
Funktionen mit Parametern
Funktionen können Parameter annehmen, damit ihre Funktionalität geändert werden kann. Parameter werden als durch Kommas getrennte Liste angegeben, wobei ihre Typen und Namen definiert werden.
func magicNumber(number1: Int)
{
print("\(number1) Is the magic number")
}
Anmerkung: Die \(number1)
-Syntax ist eine grundlegende String-Interpolation und wird verwendet, um die Ganzzahl in den String einzufügen.
Funktionen mit Parametern werden aufgerufen, indem die Funktion anhand ihres Namens angegeben wird und ein Eingabewert des Typs angegeben wird, der in der Funktionsdeklaration verwendet wird.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
Es könnte ein beliebiger Wert vom Typ Int verwendet worden sein.
func magicNumber(number1: Int, number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
Wenn eine Funktion mehrere Parameter verwendet, wird der Name des ersten Parameters nicht für den ersten Parameter benötigt, sondern für nachfolgende Parameter.
let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"
Verwenden Sie externe Parameternamen, um Funktionsaufrufe lesbarer zu machen.
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)
Durch Festlegen des Standardwerts in der Funktionsdeklaration können Sie die Funktion aufrufen, ohne Eingabewerte anzugeben.
func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
print("\(number1 + number2) Is the magic number")
}
magicNumber()
//output: "15 Is the magic number"
Werte zurückgeben
Funktionen können Werte zurückgeben, indem der Typ nach der Parameterliste angegeben wird.
func findHypotenuse(a: Double, b: Double) -> Double
{
return sqrt((a * a) + (b * b))
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
Funktionen können auch mehrere Werte mithilfe von Tupeln zurückgeben.
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)
Fehler werfen
Wenn Sie möchten, dass eine Funktion Fehler auslösen kann, müssen Sie das Schlüsselwort throws
nach den Klammern mit den Argumenten hinzufügen:
func errorThrower()throws -> String {}
Wenn Sie einen Fehler ausgeben möchten, verwenden Sie das Schlüsselwort throw
:
func errorThrower()throws -> String {
if true {
return "True"
} else {
// Throwing an error
throw Error.error
}
}
Wenn Sie eine Funktion aufrufen möchten, die einen Fehler auslösen kann, müssen Sie das Schlüsselwort try
in einem do
Block verwenden:
do {
try errorThrower()
}
Weitere Informationen zu Swift-Fehlern: Fehler
Methoden
Instanzmethoden sind Funktionen , die in Swift zu Instanzen eines Typs gehören (a class , struct , Aufzählungs oder Protokoll ). Typmethoden werden für einen Typ selbst aufgerufen.
Instanzmethoden
Instanzmethoden sind mit einer definierten func
Erklärung innerhalb der Definition des Typs oder in einer Verlängerung .
class Counter {
var count = 0
func increment() {
count += 1
}
}
Die Instanzmethode increment()
wird für eine Instanz der Counter
Klasse aufgerufen:
let counter = Counter() // create an instance of Counter class
counter.increment() // call the instance method on this instance
Typ Methoden
Typmethoden werden mit den static func
Schlüsselwörtern definiert. (Für Klassen definiert die class func
eine Typmethode, die von Unterklassen überschrieben werden kann.)
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
Inout-Parameter
Funktionen können die übergebenen Parameter ändern, wenn sie mit dem Schlüsselwort inout
gekennzeichnet sind. Wenn ein inout
Parameter an eine Funktion übergeben wird, muss der Aufrufer der übergebenen Variablen ein &
hinzufügen.
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".
Dadurch kann die Referenzsemantik auf Typen angewendet werden, die normalerweise eine Wertesemantik haben.
Syntax für den nachlaufenden Verschluss
Wenn der letzte Parameter einer Funktion eine Schließung ist
func loadData(id: String, completion:(result: String) -> ()) {
// ...
completion(result:"This is the result data")
}
Die Funktion kann mit der Trailing-Closure-Syntax aufgerufen werden
loadData("123") { result in
print(result)
}
Operatoren sind Funktionen
Operatoren wie +
, -
, ??
sind eine Art Funktion, die mit Symbolen anstelle von Buchstaben bezeichnet wird. Sie werden anders als Funktionen aufgerufen:
- Präfix:
- x
- Infix:
x + y
- Postfix:
x ++
Weitere Informationen zu grundlegenden Operatoren und fortgeschrittenen Operatoren finden Sie in The Swift Programming Language.
Variadische Parameter
Manchmal ist es nicht möglich, die Anzahl der Parameter anzugeben, die eine Funktion benötigen könnte. Betrachten Sie eine sum
:
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
Dies funktioniert gut, um die Summe von zwei Zahlen zu finden, aber um die Summe von drei zu finden, müssten wir eine andere Funktion schreiben:
func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
return a + b + c
}
und einer mit vier Parametern würde einen anderen benötigen, und so weiter. Swift ermöglicht es, eine Funktion mit einer variablen Anzahl von Parametern in einer Folge von drei Perioden zu definieren: ...
Zum Beispiel,
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, combine: +)
}
Beachten Sie, wie der numbers
, der variadisch ist, zu einem einzelnen Array
vom Typ [Int]
. Dies ist im Allgemeinen wahr, variadische Parameter vom Typ T...
sind als [T]
zugänglich.
Diese Funktion kann nun so aufgerufen werden:
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
Ein variadischer Parameter in Swift muss nicht am Ende der Parameterliste stehen, aber in jeder Funktionssignatur kann nur einer enthalten sein.
Manchmal ist es zweckmäßig, die Anzahl der Parameter auf ein Minimum zu beschränken. Zum Beispiel macht es keinen Sinn, die sum
der Nicht-Werte zu verwenden. Eine einfache Möglichkeit, dies zu erzwingen, besteht darin, einige nicht-variadische erforderliche Parameter anzugeben und anschließend den variadischen Parameter hinzuzufügen. Um sicherzustellen, dass die sum
nur mit mindestens zwei Parametern aufgerufen werden kann, können wir schreiben
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
Abonnements
Klassen, Strukturen und Aufzählungen können Subskriptionen definieren. Dabei handelt es sich um Verknüpfungen für den Zugriff auf die Elementelemente einer Collection, Liste oder Sequenz.
Beispiel
struct DaysOfWeek {
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
subscript(index: Int) -> String {
get {
return days[index]
}
set {
days[index] = newValue
}
}
}
Subskriptionsverwendung
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])
Optionen für Abonnements:
Subskripte können eine beliebige Anzahl von Eingabeparametern annehmen, und diese Eingabeparameter können von einem beliebigen Typ sein. Subskripte können auch jeden Typ zurückgeben. Subskripte können variable Parameter und variadische Parameter verwenden, jedoch keine In-Out-Parameter oder Standardparameterwerte.
Beispiel:
struct Food {
enum MealTime {
case Breakfast, Lunch, Dinner
}
var meals: [MealTime: String] = [:]
subscript (type: MealTime) -> String? {
get {
return meals[type]
}
set {
meals[type] = newValue
}
}
}
Verwendungszweck
var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"
debugPrint("I had \(diet[.Breakfast]) for breakfast")
Funktionen mit Verschlüssen
Die Verwendung von Funktionen, die Schließungen aufnehmen und ausführen, kann äußerst nützlich sein, um einen Codeblock zu senden, der an anderer Stelle ausgeführt werden soll. Wir können damit beginnen, dass unsere Funktion einen optionalen Abschluss zulässt, der (in diesem Fall) Void
.
func closedFunc(block: (()->Void)? = nil) {
print("Just beginning")
if let block = block {
block()
}
}
Nun, da unsere Funktion definiert wurde, rufen wir sie auf und übergeben etwas Code:
closedFunc() { Void in
print("Over already")
}
Durch die Verwendung eines nachlaufenden Abschlusses bei unserem Funktionsaufruf können wir Code (in diesem Fall print
) übergeben, der an einer bestimmten Stelle in unserer Funktion closedFunc()
werden soll.
Das Protokoll sollte drucken:
Gerade begonnen
Schon vorbei
Ein spezifischerer Anwendungsfall hierfür könnte die Ausführung von Code zwischen zwei Klassen umfassen:
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?()
}
}
Das Protokoll sollte drucken:
1
2
Funktionen übergeben und zurückgeben
Die folgende Funktion gibt eine andere Funktion als Ergebnis zurück, die später einer Variablen zugewiesen und aufgerufen werden kann:
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)
Funktionsarten
Jede Funktion hat einen eigenen Funktionstyp, der sich aus den Parametertypen und dem Rückgabetyp der Funktion selbst zusammensetzt. Zum Beispiel folgende Funktion:
func sum(x: Int, y: Int) -> (result: Int) { return x + y }
hat einen Funktionstyp von:
(Int, Int) -> (Int)
Funktionstypen können somit als Parametertypen oder als Rückgabetypen für Verschachtelungsfunktionen verwendet werden.