How can you provide multiple constraints on a generic type parameter in Swift?

iOS interview question for Intermediate practice.

Answer

You can provide multiple constraints on a generic type parameter in Swift by listing the required class superclass (at most one) and any required protocols after the type parameter's name and a colon (:), joining multiple protocol constraints with an ampersand (&). Syntax: 1. Multiple Protocol Constraints: List the protocols separated by &. swift func process<T: ProtocolA & ProtocolB & ProtocolC( item: T) { ... } struct MyGeneric<T: ProtocolA & ProtocolB { ... } This requires T to conform to ProtocolA AND ProtocolB AND ProtocolC. 2. Class and Protocol Constraints: List the required superclass first, followed by any protocols separated by &. swift // T must be a subclass of MySuperclass AND conform to ProtocolA func configure<T: MySuperclass & ProtocolA( item: T) { ... } // T must be a subclass of UIViewController AND conform to ProtoA and ProtoB class MyViewController<DataModel: UIViewController & ProtoA & ProtoB { ... } You can only have one class constraint. Using a where Clause: For more complex constraints or improved readability, you can also specify multiple constraints using a where clause after the function/type signature: swift func process<T, U( tValue: T, uValue: U) where T: ProtocolA & ProtocolB, U: MySuperclass & ProtocolC { // ... } Example: swift import Foundation // For NSObject protocol Nameable { var name: String { get } } protocol Loggable { func log() } // Function requires T to be a subclass of NSObject AND conform to Nameable and Loggable func processObject<T: NSObject & Nameable & Loggable( object: T) { print("Processing object named: \(object.name)") object.log() } // Example conforming type class User: NSObject, Nameable, Loggable { var name: String init(name: String) { self.name = name } func log() { print("User logged something.") } } let user = User(name: "Admin") processObject(user) // OK // class Guest: Nameable, Loggable { ... } // Error: Guest doesn't inherit NSObject // processObject(Guest()) This allows generic code to require that type parameters fulfill multiple specific requirements simultaneously.

Explanation

While you can list multiple protocols after the colon, you can only list one class type constraint, and it must come first in the list.

Related Questions