A brief introduction to the Swift generics

Generics are commonly used in classes, structs, functions, and enumerations. Their introduction serves as a placeholder, where the type is not known until the function is called.

For example, Array and Dictionry are both generic sets. We can create an Array of type String or an Array of type Int, and we can store various types of data while creating a Dictionary

Here’s an example of a real world scenario where we receive a request to add an Int array to the end of the array.

// Define a function that appends array data to a specified array. Func appendIntToArray(SRC :[Int]) [Int]) {// iterate over and add to array for element in SRC {dest.append(element)}} // add array data with appendIntToArray var arr = AppendIntToArray (SRC: [2,3], dest: &arr) print(arr) // [22,15, 2,3]Copy the code

Now, you’ve just completed this requirement, and your product comes along and says no, we need to change this, and we need to be able to append strings as well

AppendStringToArray (SRC :[String]); dest:inout [String]) { for element in src { dest.append(element) } } var strArr = ["OC","Swift"] appendStringToArray(src: ["C", "C++"], dest: &strArr) print(strArr) /// ["OC", "Swift", "C", "C++"]Copy the code

If the product asks us to add another type of data, then we find that as long as we add a new type of data we need a method to implement, which is not easy to maintain the code is not readable, we will use generics to solve this problem

Var arr2 = [15,28] appendArray(SRC: [39,58], dest: &arr2) print(arr2) // [15, 28, 39, 58] var strArr2 = ["OC","Swift"] appendArray(src: ["OC","Swift"], dest: Var doubleArr = [1.4,2.4] appendArray(SRC: [5.5,4.6], dest: &doublearr) print(doubleArr) // [1.4, 2.4, 5.5, 4.6]Copy the code

In fact, simple to understand, like a row of no name of the bench, three can come to sit Li Si can come to sit, very convenient to use

Simple use of generics

1. Generic functions, as shown above. Pansystem functions are mainly written as follows:

// define generic function func < generic 1, generic 2... >(parameter list)-> Return value type {// function body... }Copy the code

Take an actual example of swapping the values of two strings

Func changeValueToValue<T>(value1: inout T,value2: inout T) { let value3 = value1 value1 = value2 value2 = value3 } var str1 = "2222"; var str2 = "3333"; print(str1+str2) // 22223333 changeValueToValue(value1: &str1, value2: &str2) print(str1+str2) // 33332222Copy the code

2. Generic constraints, add constraints * for generic types

Generic constraints are divided into the following categories:

A generic type must be a subclass of a certain class. A generic type must comply with certain protocol conditions. A generic type must satisfy certain protocol conditions. Inherit from parent >(argument list) -> return value {// body of function, generic type is a subclass type of a class} // Protocol constraints use the format func function name < generic: Func < generic type 1, generic type 2 where condition >(parameter list) -> return value {// function body, generic type meets certain conditions}Copy the code

Examples of using inheritance constraints:

The class Person {func des () {print (" I am a Person ")}} class Man: Person {override func des () {print (" I am a Man ")}} to the class WoMan:Person {override func des() {print(" I am a WoMan ")}} Func PersonIs<T:Person>(Person :T) {person.des()} PersonIs(Person: Person()) // I am a PersonIs(Person: Man()) // I am a PersonIs(Person: Man()) // I am a PersonIs(Person: WoMan()) // I am a WoManCopy the code

Example of using protocol constraints:

Equatable is a standard protocol library for Swift. = contrast of inequalities

/// -parameters: /// -array: array /// -value: Target func findValueIsIn<T:Equatable>(array:[T],value:T) -> Bool {for element in array {if element == value {// Return true}} return false} // findValueIsIn(array: ["222","000","1212"], value: FindValueIsIn (array: [22.2,3.03,4.56], value: 0) // falseCopy the code

Examples of conditional constraint use:

// Define a generic protocol. Unlike other generic types, the generic protocol Stackable{// declare an associatedType, using the associatedType keyword associatedType ItemType mutating func add(item:ItemType) mutating func ret() -> ItemType } struct Stack<T>:Stackable{ var store = [T]() mutating  func add(item: T) {store.append(item)} mutating func ret() -> T {return store.removelast ()}} // Create Stack structure with generic type String var stackOne = Stack<String>() stackOne.add(item: "111") stackOne.add(item: "222") stackOne.add(item: Ret () print("t = \(t) stackOne = \(stackOne)") // Result :t = 333 stackOne = Stack<String>(store: ["111", "222"]) func addItemOneToTwo<T1:Stackable, T2:Stackable> (stackOne: inout T1,stackTwo: inout T2) where T1.ItemType == T2.ItemType { let stckoneItem = stackOne.ret() stackTwo.add(item: stckoneItem) } var stackTwo = Stack<String>() addItemOneToTwo(stackOne: &stackOne, stackTwo: &stackTwo) print("stackone= \(stackOne) stackTwo = \(stackTwo) ") //stackone= Stack<String>(store: ["111"]) stackTwo = Stack<String>(store: ["222"])Copy the code