1. Type constraints

  • You can define type constraints by placing a class or protocol name separated by a colon after a type parameter name, which will become part of the type parameter list. The basic syntax for adding type constraints to generic functions is as follows (the same syntax applies to generic types) :

  • The following shows a generic version of the findIndex(ofString:in:) function. Notice that the return value of this function is still of type Int, okay? This is because the function returns an optional index number rather than an optional value from the array. Note that this function will not compile, for reasons explained later in the example:

  • The function written above will not compile. The problem is the equality check, if value == valueToFind. Not all Swift types can be compared using the equality character (==). For example, if you create a custom class or structure to represent a complex data model, Swift cannot guess what “equal” means to that class or structure.

  • The Swift standard library defines an Equatable protocol, which requires that any type that follows this protocol must implement equality (==) and inequality (! =), all Swift standard types automatically support the Equatable protocol

  • The only type argument to findIndex(of:in:) is written as T: Equatable, which means “any type T that matches the Equatable protocol

2. Association type

  • When defining a protocol, it can sometimes be useful to declare one or more association types as part of the protocol definition. An association type provides a placeholder name (or alias name) for a type in a protocol that represents the actual type specified when the protocol is adopted. You can specify an association type by using the associatedType keyword.

  • The protocol does not specify the type of the element in the container. It only specifies the methods that must be implemented to comply with the protocol. It also declares the ItemType association type of the AssociatedType. This protocol cannot define what type of ItemType is aliased. Will this information be provided by protocol-compliant types

  • IntStack complies with the Container protocol, which requires methods to implement the protocol, specifying the true type of the association type.

  • Typealias ItemType = Int, append(item:), append(item:)

  • Stack complies with the Container protocol. Stack is the type of the Container. Append (item:) is the type of the Container

3. The paradigmwherestatements

  • It is also useful to define constraints for associated types, which can be defined in a parameter list using the WHERE statement.

  • Where Usage Scenario

  • The WHERE statement requires that the association type complies with a specific protocol and that the type of a parameter must be the same as the type of the association type.

  • You can define a WHERE statement, followed by a list of parameters, followed by a WHERE clause with one or more constraints on the association type, and an equality relationship between one or more parameter types and the association type.

  • You can add a WHERE statement before a function body or type brace

  • The example checks whether the two containers are the same, the number of elements, the order, and the values in the order are the same.

  • This function takes someContainer and anotherContainer. The someContainer parameter is of type C1 and the anotherContainer parameter is of type C2. C1 and C2 are placeholder type parameters of the container, whose type is determined when the function is called

  • C1 must comply with the Container protocol (C1: Container). C2 must comply with the Container protocol (written C2: Container).

  • C1’s ItemType must be of the same type as C2’s ItemType. C1’s ItemType must conform to the Equatable protocol. The third and fourth requirements are defined as a WHERE clause, written after the keyword WHERE. They are also part of the generic function type parameter list

  • SomeContainer and anotherContainer can pass! = operates on the elements