Generic code lets you write flexible, reusable functions that can be used for any type, depending on the requirements you define. Generics are one of Swift’s most powerful features, and much of the Swift standard library is built on generic code.

Generics parameterize types, increasing code reuse and reducing code volume.

The #### generic function uses a “placeholder type” that specifies that arguments A and b must both be of the same type T (let’s just call it T), or the type represented by T.

Generic functions can be used with any type.

Here’s an example:

func swapValues<T>(_ a: inout T, _ b: inout T) { 
    (a, b) = (b, a)
}

var aa = 10
var bb = 20
swapValues(&aa, &bb)
Copy the code

Where T, T is automatically inferred to be Int. T can also be any other type such as String. This eliminates the need to write a function for string swapping. Just call the swapValues function.

#### Generic types Swift allows you to define your own generic types. They are custom classes, structures, and enumerations that can be used for any type, similar to Array and Dictionary.

For example, a custom Stack can easily store data into an array.

Struct Stack<Element> {var items = [Element]() mutating func push(_ item: Element) {items.append(item)} mutating func pop() -> Element {return items.removelast ()}} Var stackOfStrings = Stack<String>() stackofstrings.push ("uno") stackofstrings.push (" DOS ") stackOfStrings.push("tres")Copy the code

#### Associated Type

When defining a protocol, it is sometimes useful to declare one or more association types in the protocol definition. Associative types are those that assign a “placeholder type” T to the type used in the protocol. The actual type of T is not specified until the protocol is adopted. The association type is specified by the associatedType keyword.

Protocol Stackable {associatedType Element // AssociatedType Element Element) mutating func pop() -> Element func top() -> Element func size() -> Int } class StringStack : Stackable {// set the association type to String TypeAlias Element = String typeAlias keyword, Var elements = [String]() func push(_ element: String) { elements.append(element) } func pop() -> String { elements.removeLast() } func top() -> String { elements.last! } func size() -> Int { elements.count } } var ss = StringStack() ss.push("Jack") ss.push("Rose")Copy the code

Multiple association types can also be declared in a protocol

The #### type constraint indicates that a type formal parameter must inherit from a particular class or follow a particular protocol or combination protocol.

Func swapValues<T: Person & Runnable>(_ a: inout T, _ b: inout T) { (a, b) = (b, a) } }Copy the code

The nature of the optional is enum type

public enum Optional<Wrapped> : ExpressibleByNilLiteral { 
    case none
    case some(Wrapped)
    public init(_ some: Wrapped) 
}

var age: Int? = 10
var age0: Optional<Int> = Optional<Int>.some(10) var age1: Optional = .some(10)
var age2 = Optional.some(10)
var age3 = Optional(10)
age = nil
age3 = .none
Copy the code