EMZETT.
Login

Kurz: Swift-Funktionen haben Argumentbezeichner, die den Aufruf lesbar machen wie einen Satz:

Teil des Kurses Swift

Kapitel 3 von 8 im Kurs Swift (Abschnitt „Daten und Funktionen“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Funktionen

Swift-Funktionen haben Argumentbezeichner, die den Aufruf lesbar machen wie einen Satz:

func gruss(an name: String, mit anrede: String = "Hallo") -> String {
    return "\(anrede), \(name)!"
}
 
func quadrat(_ x: Int) -> Int { x * x }           // _ : kein Bezeichner beim Aufruf; Einzeiler ohne return
 
func minMax(_ zahlen: [Int]) -> (min: Int, max: Int) {
    (zahlen.min()!, zahlen.max()!)                 // Rückgabe als benanntes Tupel
}
 
func summe(_ zahlen: Int...) -> Int { zahlen.reduce(0, +) }      // variadisch
 
func tausche(_ a: inout Int, _ b: inout Int) {     // inout: Variable wird verändert
    let t = a; a = b; b = t
}
 
func fakultaet(_ n: Int) -> Int { n <= 1 ? 1 : n * fakultaet(n - 1) }
 
print(gruss(an: "Mia"), gruss(an: "Tom", mit: "Hi"))
print(quadrat(7), summe(1, 2, 3, 4), fakultaet(10))
let ergebnis = minMax([4, 9, 1, 7])
print(ergebnis.min, ergebnis.max, ergebnis)
var x = 1, y = 2
tausche(&x, &y)
print(x, y)
 
func addierer(_ n: Int) -> (Int) -> Int { { $0 + n } }          // Funktion als Rückgabewert
let plus5 = addierer(5)
print(plus5(10), addierer(1)(1))

Ausgabe:

Hallo, Mia! Hi, Tom!
49 10 3628800
1 9 (min: 1, max: 9)
2 1
15 2

Closures

Ein Closure ist eine namenlose Funktion { (Parameter) -> Rückgabe in Code }. Sie kann Variablen aus ihrer Umgebung einfangen.

let verdoppeln = { (x: Int) -> Int in x * 2 }
print(verdoppeln(21))
 
let zahlen = [5, 3, 8, 1, 9, 2]
print(zahlen.sorted())
print(zahlen.sorted(by: >))
print(zahlen.sorted { $0 % 3 < $1 % 3 })       // $0, $1: Kurzschreibweise
print(zahlen.map { $0 * $0 })
print(zahlen.filter { $0 > 4 })
print(zahlen.reduce(0) { $0 + $1 })
print(zahlen.contains { $0 > 8 }, zahlen.allSatisfy { $0 > 0 }, zahlen.first { $0 > 5 } as Any)
print(zahlen.compactMap { $0 > 4 ? String($0) : nil })
print([[1, 2], [3]].flatMap { $0 })
print(zip(zahlen, "abc").map { "\($1)\($0)" })
 
func zaehler() -> () -> Int {
    var n = 0
    return { n += 1; return n }              // fängt n ein
}
let z = zaehler()
_ = z(); _ = z()
print(z())
 
func wiederhole(_ n: Int, aktion: () -> Void) { for _ in 0..<n { aktion() } }
wiederhole(3) { print("*", terminator: "") }  // Trailing Closure
print()

Ausgabe:

42
[1, 2, 3, 5, 8, 9]
[9, 8, 5, 3, 2, 1]
[3, 9, 1, 5, 8, 2]
[25, 9, 64, 1, 81, 4]
[5, 8, 9]
28
true true Optional(8)
["5", "8", "9"]
[1, 2, 3]
["a5", "b3", "c8"]
3
***

Arrays

var f = ["Apfel", "Birne", "Kirsche"]
f.append("Dattel")
f.insert("Ananas", at: 0)
f.remove(at: 2)
print(f, f.count, f.first!, f.last!, f[1], f[1...2])
f += ["Erdbeere"]
print(f.sorted(), f.reversed() as [String], f.contains("Birne"), f.firstIndex(of: "Dattel") as Any)
print(f.joined(separator: ", "), f.map(\.count), f.filter { $0.hasPrefix("A") })
var zahlen = [5, 3, 9, 1]
zahlen.sort()
zahlen.removeAll { $0 > 6 }
print(zahlen, zahlen.sum, zahlen.reduce(0, +))
let matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2], matrix.map { $0.reduce(0, +) }, matrix.joined())
print(Array(repeating: 0, count: 3), Array(1...5), (1...5).map { $0 * 2 })
print(zahlen.isEmpty, [Int]().isEmpty, zahlen.min()!, zahlen.max()!)
print(Array(zahlen.prefix(2)), Array(zahlen.suffix(1)), zahlen.dropFirst())
 
extension Array where Element: Numeric {
    var sum: Element { reduce(0, +) }
}

Ausgabe:

["Ananas", "Apfel", "Kirsche", "Dattel"] 4 Ananas Dattel Apfel ["Apfel", "Kirsche"]
["Ananas", "Apfel", "Dattel", "Erdbeere", "Kirsche"] ["Erdbeere", "Dattel", "Kirsche", "Apfel", "Ananas"] false Optional(3)
Ananas, Apfel, Kirsche, Dattel, Erdbeere [6, 5, 7, 6, 8] ["Ananas", "Apfel"]
[1, 3, 5] 9 9
6 [6, 15] FlattenSequence<Array<Array<Int>>>(_base: [[1, 2, 3], [4, 5, 6]])
[0, 0, 0] [1, 2, 3, 4, 5] [2, 4, 6, 8, 10]
false true 1 5
[1, 3] [5] [3, 5]

Dictionaries und Sets

var alter = ["Mia": 17, "Tom": 25]
alter["Zoe"] = 31
alter["Tom"] = nil                              // entfernen
print(alter["Mia"]!, alter["Ben"] as Any, alter["Ben", default: 0], alter.count)
for (name, a) in alter.sorted(by: { $0.key < $1.key }) {     // Dictionary hat keine feste Reihenfolge!
    print("\(name): \(a)")
}
print(alter.keys.sorted(), alter.values.sorted(), alter.mapValues { $0 + 1 }.sorted { $0.key < $1.key })
var zaehler: [Character: Int] = [:]
for c in "mississippi" { zaehler[c, default: 0] += 1 }
print(zaehler.sorted { $0.key < $1.key }.map { "\($0.key)\($0.value)" }.joined(separator: " "))
let gruppen = Dictionary(grouping: ["ein", "kleiner", "langer", "Satz", "mit"], by: { $0.count })
print(gruppen.keys.sorted(), gruppen[3]!.sorted())
 
var menge: Set = [3, 1, 2, 3, 1]
menge.insert(9)
print(menge.count, menge.contains(2), menge.sorted())
print(Set([1, 2, 3]).intersection([2, 3, 4]).sorted(), Set([1, 2]).union([2, 3]).sorted(), Set([1, 2, 3]).subtracting([2]).sorted())

Ausgabe:

17 nil 0 2
Mia: 17
Zoe: 31
["Mia", "Zoe"] [17, 31] [(key: "Mia", value: 18), (key: "Zoe", value: 32)]
i4 m1 p2 s4
[3, 4, 6, 7] ["ein", "mit"]
4 true [1, 2, 3, 9]
[2, 3] [1, 2, 3] [1, 3]

Merke

  • Funktionen: func name(label param: Typ) -> Rückgabe, _ für kein Label, inout, variadisch
  • Closures { $0 + $1 }, Trailing Closure, map/filter/reduce/sorted/compactMap
  • Arrays, Dictionaries (ohne feste Reihenfolge), Sets
  • Collections sind Werttypen (Kopie beim Zuweisen)

Übungsaufgabe

Zähle mit einem Dictionary die Wörter eines Satzes und gib sie sortiert aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Typen, Optionals und Kontrollfluss

Weiter: Structs, Klassen und Enums

Alle Kapitel: Swift im Überblick