Latest web development tutorials

Swift Generics

Swift stellt eine generische flexibel und ermöglicht es Ihnen, wiederverwendbare Funktionen und Typen zu schreiben.

Swift-Standardbibliothek wird von generischem Code aufgebaut werden.

Swift-Arrays und Wörterbücher Typen sind generischen Satz.

Sie können ein Int-Array zu erstellen, können Sie ein String-Array zu erstellen, oder auch Daten-Array jede Art von anderen Swift sein kann.

Das folgende Beispiel ist eine nicht-generische Funktion Austausch für den Austausch von zwei Int-Werte:

// 定义一个交换两个变量的函数
func exchange(inout a: Int, inout b: Int) {
    let temp = a
    a = b
    b = temp
}

var numb1 = 100
var numb2 = 200

print("交换前数据: \(numb1) 和 \(numb2)")
exchange(&numb1, b: &numb2)
print("交换后数据: \(numb1) 和 \(numb2)")

Die obige Programmausführung Ausgabe ist:

交换前数据: 100 和 200
交换后数据: 200 和 100

Hauptfunktionen können jede Art zuzugreifen, wie Int oder String.

Das folgende Beispiel ist eine generische Funktion für den Austausch Swap zwei Int und String-Werte:

func exchange<T>(inout a: T, inout b: T) {
    let temp = a
    a = b
    b = temp
}

var numb1 = 100
var numb2 = 200

print("交换前数据:  \(numb1) 和 \(numb2)")
exchange(&numb1, b: &numb2)
print("交换后数据: \(numb1) 和 \(numb2)")

var str1 = "A"
var str2 = "B"

print("交换前数据:  \(str1) 和 \(str2)")
exchange(&str1, b: &str2)
print("交换后数据: \(str1) 和 \(str2)")

Die obige Programmausführung Ausgabe ist:

交换前数据:  100 和 200
交换后数据: 200 和 100
交换前数据:  A 和 B
交换后数据: B 和 A

Generika-Version dieser Funktion den Platzhalter Typnamen (in der Regel durch den Buchstaben T in diesem Fall dargestellt) anstelle der tatsächlichen Typnamen (wie Int, String oder Doppel). Platzhalterart Name darf nicht vorschlagen, welche Art T, aber es schlägt vor, a und b müssen vom gleichen Typ T sein, unabhängig davon, welche Art T darstellt. Nur Austausch (_: _ :) Funktion, wenn in jedem Anruftyp, um die tatsächliche Typ T darstellt, um zu bestimmen geben.

Ein weiterer Unterschied besteht darin, dass diese letztere Funktion Name durch die Gattungsbezeichnung des Platzhalter-Typ (T) in spitzen Klammern gefolgt wird ( ). Die spitzen Klammern gesagt Swift dass T ist der Austausch (_: _ :) eine Funktion des Typs definiert. Da T ein Platzhalter namens Typ ist, ist Swift nicht den Namen des tatsächlichen Typ T zu finden


Generisches Art

Swift können Sie Ihre eigene generische Typen zu definieren.

Benutzerdefinierte Klassen, Strukturen und Aufzählungen auf jede Art als Array und Wörterbuch Nutzung angewendet.

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("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("类型参数")
print(tos.items)

tos.push("类型参数名")
print(tos.items)


let deletetos = tos.pop()

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]

Erweiterte generische Typ

Wenn Sie eine generische Art von Zeit (Erweiterung mit Stichworten) erweitern, brauchen Sie keinen Typ Parameterliste in der erweiterten Definition zu liefern. Bequemer ist es, dass bei der Verwendung in der Liste angegebenen Typdefinition Typparameter primitiv und die Parameternamen aus der ursprünglichen Art erweitert werden kann, wird als Verweis auf die ursprüngliche Definition des Typs Parameter verwendet werden.

Beispiele

Das folgende Beispiel erweitert die allgemeine TOS-Typ, eine schreibgeschützte Eigenschaft erste Berechnung genannt hinzuzufügen, wird es die aktuelle Spitze der Stapelelemente zurückkehren und werden nicht aus dem Stapel entfernt werden.

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("Swift")
print(tos.items)

tos.push("泛型")
    print(tos.items)
    
    tos.push("类型参数")
    print(tos.items)
    
    tos.push("类型参数名")
    print(tos.items)

// 扩展泛型 TOS 类型
extension TOS {
    var first: T? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

if let first = tos.first {
    print("栈顶部项:\(first)")
}

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]
栈顶部项:类型参数名

Typ-Einschränkung

Typ-Einschränkung gibt an, dass ein Typ-Parameter aus der angegebenen Klasse erben müssen oder ein bestimmtes Protokoll oder Zusammensetzung folgen.

Typ Einschränkung Syntax

Sie können durch einen Doppelpunkt, als Teil der Typparameter Kette eine Art Zwang in der Rückseite eines Typ-Parameternamen, geteilt schreiben. Solche Handlungen auf der Grundlage der Art der Einschränkung Syntax für generische Funktionen sind wie folgt (die gleiche allgemeine Art der Syntax):

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
    // 这里是函数主体
}

Beispiele

// 函数可以作用于查找一字符串数组中的某个字符串
func findStringIndex(array: [String], _ valueToFind: String) -> Int? {
    for (index, value) in array.enumerate() {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

let strings = ["cat", "dog", "llama", "parakeet", "terrapin"]
if let foundIndex = findStringIndex(strings, "llama") {
    print("llama 的下标索引值为 \(foundIndex)")
}

Die obige Programmausführung Ausgabe ist:

llama 的下标索引值为 2

Beispiele für die Art der Assoziation

Swift typealias Stichwort, um die Art der Vereinigung zu setzen verwendet.

Definieren Sie ein Protokoll, manchmal erklären, ein oder mehrere zugehörige Protokolltyp Teil der Definition ist sehr nützlich, da.

protocol Container {
    // 定义了一个ItemType关联类型
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

// 遵循Container协议的泛型TOS类型
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)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> T {
        return items[i]
    }
}

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

tos.push("泛型")
print(tos.items)

tos.push("参数类型")
print(tos.items)

tos.push("类型参数名")
print(tos.items)

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "参数类型"]
["Swift", "泛型", "参数类型", "类型参数名"]

wo Aussagen

Die Art der Randbedingung der Einhaltung der Definition der Art von Einschränkung generische Funktion oder Klasse zu gewährleisten.

Sie können die Parameter der Anweisung, wo die Einschränkung in der Parameterliste definieren.

Wo können Sie eine Anweisung schreiben, gefolgt von der Typparameterliste auf der Rückseite, wo die Aussage durch eine oder mehrere Arten von Beschränkungen für den Verein anschließt, und (oder), das Äquivalent von einem oder mehreren Typen und Assoziationstypen zwischen (Gleichheit) Beziehung.

Beispiele

Das folgende Beispiel definiert eine generische Funktion allItemsMatch genannt, überprüft, ob zwei Instanzen von Container die gleichen Elemente in der gleichen Reihenfolge enthält.

Wenn alle können die Elemente übereinstimmen, kehrt dann in einen Booleschen Wert true, sonst ist es falsch ist.

protocol Container {
    typealias 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)
    }
    
    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 {
        // 检查两个Container的元素个数是否相同
        if someContainer.count != anotherContainer.count {
            return false
        }
        
        // 检查两个Container相应位置的元素彼此是否相等
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        // 匹配所有项,返回 true
        return true
}

var tos = Stack<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("Where 语句")
print(tos.items)

var eos = ["Swift", "泛型", "Where 语句"]
print(eos)

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "Where 语句"]
["Swift", "泛型", "Where 语句"]