Latest web development tutorials

Swift rodzajowych

Swift zapewnia ogólny elastyczny i pozwala na pisanie wielokrotnego funkcje i rodzaje.

Swift standardowa biblioteka jest zbudowany z kodem rodzajowy.

Swift tablice i słowniki są ogólne typy set.

Można utworzyć tablicę int, można utworzyć tablicę ciągów, a nawet tablicę danych może być dowolny rodzaj innego Swift.

Poniższy przykład jest non-generic wymiany funkcja wymiany dwóch wartości Int:

// 定义一个交换两个变量的函数
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)")

Wyjście powyżej wykonywanie programu jest:

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

Funkcje generyczne mogą uzyskać dostęp do wszelkiego rodzaju, takich jak int lub String.

Poniższy przykład jest rodzajowy funkcja wymiany zamiany dwóch wartości int wyrażenie:

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)")

Wyjście powyżej wykonywanie programu jest:

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

Generic wersja tej funkcji za pomocą nazwy typu zastępczy (zazwyczaj reprezentowany przez literę T w tym przypadku) zamiast rzeczywistych nazw typów (takich jak int, string lub podwójne). Zastępczy nazwa typu nie może sugerować, jakiego typu T, ale sugeruje, A i B muszą być tego samego typu T, niezależnie od tego, jakiego typu T reprezentuje. Tylko wymiana (_: _ :) funkcji, gdy przeszedł do każdego typu połączeń w celu określenia rzeczywistego typu T reprezentuje.

Inną różnicą jest to, że ta ostatnia nazwa funkcji następuje nazwą rodzajową rodzaju zastępczego (t) jest w nawiasach kątowych ( ). Wsporniki kątowe powiedziano Swift, że T jest wymiana (_: _ :) funkcją typu zdefiniowane. Ponieważ T jest zastępczy o nazwie typu Swift nie może znaleźć nazwę rzeczywistego typu T.


Ogólny typ

Swift pozwala definiować własne typy generyczne.

Własne klasy, struktury i wyliczenia stosowane do każdego rodzaju jak Array i słownik użytkowania.

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()

Wyjście powyżej wykonywanie programu jest:

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

Rozszerzony typ ogólny

Po przedłużeniu ogólny typ czasu (rozszerzenie za pomocą słów kluczowych), nie ma potrzeby, aby dostarczyć listę parametr typu w rozszerzonej definicji. Wygodniejsze jest prymitywne, że definicja typu parametru typ zadeklarowany w wykazie mogą być rozszerzane w użyciu i nazwy parametrów z oryginalnego typu zostaną wykorzystane jako punkt odniesienia do pierwotnej definicji parametru typu.

Przykłady

Poniższy przykład przedłuża ogólny typ TOS dodać tylko do odczytu o nazwie pierwsze obliczenie, zwróci Top elementów stosu i nie zostaną usunięte ze stosu.

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)")
}

Wyjście powyżej wykonywanie programu jest:

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

Rodzaj ograniczenia

Rodzaj ograniczenia określa, że ​​parametr typu musi dziedziczyć z określonej klasy lub śledzić konkretny protokół lub kompozycję.

Składnia ograniczenie Rodzaj

Można napisać ograniczenie typu w tylnej części nazw parametrów typu, podzielonej przez jelita grubego, jako część łańcucha parametrów typu. Takie akty na podstawie rodzaju przymusu składni funkcji generycznych są następujące (tego samego rodzaju składni):

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

Przykłady

// 函数可以作用于查找一字符串数组中的某个字符串
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)")
}

Wyjście powyżej wykonywanie programu jest:

llama 的下标索引值为 2

Przykłady rodzaju stowarzyszenia

Swift typealias słowo kluczowe użyte do ustawiania rodzaju stowarzyszenia.

Określ protokół, czasami zadeklarować jedną lub więcej powiązanych rodzaj części protokołu definicji jest bardzo przydatna jako.

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)

Wyjście powyżej wykonywanie programu jest:

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

W przypadku stwierdzenia

Rodzaj przymusu, aby zapewnić zgodność z definicji typu rodzajowego od ograniczeń funkcji lub klasy.

Można zdefiniować parametry rachunku gdzie ograniczenie na liście parametrów.

Gdzie można napisać oświadczenie, a następnie na liście parametrów typu z tyłu, gdzie jest instrukcja, a następnie przez jeden lub więcej rodzajów ograniczeń dla stowarzyszenia i (lub) równowartość jednego lub więcej typów i rodzajów stowarzyszeniu między (równość) relacji.

Przykłady

Poniższy przykład definiuje funkcję o nazwie rodzajowej allItemsMatch, używany w celu sprawdzenia, czy dwa przypadki pojemnik zawiera te same elementy w tej samej kolejności.

Jeśli wszystkie elementy można dopasować, a następnie powrót do wartości logicznej true, w przeciwnym razie false.

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)

Wyjście powyżej wykonywanie programu jest:

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