Latest web development tutorials

Swift Дженерики

Swift обеспечивает общий гибкий и позволяет писать повторно используемые функции и типы.

Swift стандартная библиотека построена путем общего кода.

Swift массивы и типы словарей являются универсальными набор.

Вы можете создать массив Int, вы можете создать массив строк, или даже массив данных может быть любым типом другого Swift.

Следующий пример не является родовая функция обмена для обмена двух 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)")

Выход выше выполнение программы:

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

Общие функции могут получить доступ к любому типу, такие как Int или String.

Следующий пример является обобщенная функция для обмена замены двух значений Int и строка:

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

Выход выше выполнение программы:

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

Generic версии этой функции, используя имя типа заполнитель (обычно обозначается буквой Т в данном случае) вместо фактических имен типов (например, Int, String или Double). Имя типа Заполнитель не должен предположить, что тип T, но это предполагает, а и б должны быть того же типа T, независимо от того, какой тип Т представляет. Только обмен (_: _ :) функция при передаче каждого типа вызовов, чтобы определить фактический тип T представляет.

Другим отличием является то, что это последнее имя функции с последующим родовым названием типа заполнитель (T) заключен в угловые скобки ( ). Угловые скобки сказал Свифт, что T является обмен (_: _ :) функция типа, определенного. Так как Т является заполнителем с именем типа, Swift не найти имя фактического типа T.


Общий тип

Swift позволяет определить свои собственные обобщенные типы.

Пользовательские классы, структуры и перечислений применены к любому типу как массив и словарь использования.

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

Выход выше выполнение программы:

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

Расширенная универсальный тип

При расширении общий тип времени (расширение с помощью ключевых слов), вам не нужно предоставить список параметров типа в расширенном определении. Более удобным является примитивным, что параметр типа определение типа объявляются в списке может быть расширен в использовании и имена параметров от исходного типа будет использоваться в качестве ссылки на первоначальное определение параметра типа.

примеров

Следующий пример расширяет общий тип TOS, чтобы добавить свойство только для чтения с именем Первый расчет, то он вернет текущую вершину стека элементов и не будут удалены из стека.

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

Выход выше выполнение программы:

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

Тип ограничения

Тип ограничение указывает, что параметр типа должен наследовать от указанного класса или следовать за конкретный протокол или композицию.

Синтаксис Тип ограничения

Вы можете написать ограничение типа в задней части имен параметров типа, разделенный двоеточием, как часть цепи параметра типа. Такие действия на основе типа ограничений синтаксиса родовых функций следующим образом (тот же общий тип синтаксиса):

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

примеров

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

Выход выше выполнение программы:

llama 的下标索引值为 2

Примеры типа ассоциации,

Swift typealias ключевое слово, используемое для установки типа объединения.

Она определяет протокол, когда иногда объявить один или более связанный тип протокола части определения является очень полезным, как.

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)

Выход выше выполнение программы:

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

Где заявления

Тип ограничений для обеспечения соответствия с определением типа ограничения обобщенной функции или класса.

Вы можете определить параметры инструкции, где ограничение в списке параметров.

Где вы можете написать заявление, за которым следует список параметров типа в задней части, где утверждение следует один или более типов ограничений для объединения, и (или) эквивалент одного или нескольких типов и типов ассоциаций между (равенство) отношений.

примеров

Следующий пример определяет обобщенную функцию с именем allItemsMatch, используемый для проверки два экземпляра контейнера, содержит ли одни и те же элементы в том же порядке.

Если все элементы могут совпадать, а затем вернуться в логическое значение истины, в противном случае оно ложно.

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)

Выход выше выполнение программы:

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