Swift - Generika

Die Sprache Swift 4 bietet allgemeine Funktionen zum Schreiben flexibler und wiederverwendbarer Funktionen und Typen. Generika werden verwendet, um Doppelarbeit zu vermeiden und Abstraktion bereitzustellen. Swift 4-Standardbibliotheken werden mit generischem Code erstellt. Swift 4s-Typen 'Arrays' und 'Dictionary' gehören zu generischen Sammlungen. Mit Hilfe von Arrays und Wörterbüchern werden die Arrays so definiert, dass sie 'Int'-Werte und' String'-Werte oder andere Typen enthalten.

func exchange(a: inout Int, b: inout Int) {
   let temp = a
   a = b
   b = temp
}

var numb1 = 100
var numb2 = 200

print("Before Swapping values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping values are: \(numb1) and \(numb2)")

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

Before Swapping values are: 100 and 200
After Swapping values are: 200 and 100

Allgemeine Funktionen: Typparameter

Generische Funktionen können verwendet werden, um auf jeden Datentyp wie 'Int' oder 'String' zuzugreifen.

func exchange<T>(a: inout T, b: inout T) {
   let temp = a
   a = b
   b = temp
}
var numb1 = 100
var numb2 = 200

print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")

var str1 = "Generics"
var str2 = "Functions"

print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics

Der Funktionsaustausch () wird verwendet, um Werte auszutauschen, der im obigen Programm beschrieben ist, und <T> wird als Typparameter verwendet. Zum ersten Mal wird function exchange () aufgerufen, um 'Int'-Werte zurückzugeben, und beim zweiten Aufruf von function exchange () werden' String'-Werte zurückgegeben. In die durch Kommas getrennten spitzen Klammern können mehrere Parametertypen eingefügt werden.

Typparameter werden als benutzerdefiniert bezeichnet, um den Zweck des darin enthaltenen Typparameters zu kennen. Swift 4 bietet <T> als generischen Typparameternamen. Typparameter wie Arrays und Wörterbücher können jedoch auch als Schlüsselwert benannt werden, um zu identifizieren, dass sie zum Typ 'Wörterbuch' gehören.

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

let deletetos = tos.pop()

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Erweitern eines generischen Typs

Das Erweitern der Stack-Eigenschaft, um den oberen Rand des Elements zu ermitteln, ist im Schlüsselwort 'extension' enthalten.

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

extension TOS {
   var first: T? {
      return items.isEmpty ? nil : items[items.count - 1]
   }
}
if let first = tos.first {
   print("The top item on the stack is \(first).")
}

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

["Swift 4"]
["Swift 4", "Generics"]
["Swift 4", "Generics", "Type Parameters"]
["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"]
The top item on the stack is Naming Type Parameters.

Geben Sie Einschränkungen ein

In der Sprache Swift 4 können 'Typeinschränkungen' angeben, ob der Typparameter von einer bestimmten Klasse erbt, oder den Protokollkonformitätsstandard sicherstellen.

func exchange<T>(a: inout T, b: inout T) {
   let temp = a
   a = b
   b = temp
}
var numb1 = 100
var numb2 = 200

print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")

var str1 = "Generics"
var str2 = "Functions"

print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics

Zugehörige Typen

Mit Swift 4 können zugeordnete Typen innerhalb der Protokolldefinition mit dem Schlüsselwort 'Associatedtype' deklariert werden.

protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct TOS<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
   
   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Where-Klauseln

Mithilfe von Typeinschränkungen kann der Benutzer Anforderungen an die Typparameter definieren, die einer generischen Funktion oder einem generischen Typ zugeordnet sind. Zum Definieren von Anforderungen für zugeordnete Typen 'where'-Klauseln werden als Teil der Typparameterliste deklariert. Das Schlüsselwort 'where' wird unmittelbar nach der Liste der Typparameter platziert, gefolgt von Einschränkungen der zugeordneten Typen, Gleichheitsbeziehungen zwischen Typen und zugeordneten Typen.

protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }

   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
   // check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }
   
   // check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
   // all items match, so return true
   return true
}  
var tos = Stack<String>()

tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]