Protocols with associated types let you define a blueprint with a placeholder type. This helps write flexible and reusable code that works with different data types.
Protocol with associated types in Swift
protocol ProtocolName { associatedtype TypeName func someFunction(param: TypeName) }
associatedtype declares a placeholder type inside the protocol.
The actual type is specified by the type that adopts the protocol.
Item and is set by the conforming type.protocol Container { associatedtype Item mutating func append(_ item: Item) var count: Int { get } subscript(i: Int) -> Item { get } }
Container and sets Item to Int.struct IntStack: Container { var items = [Int]() mutating func append(_ item: Int) { items.append(item) } var count: Int { items.count } subscript(i: Int) -> Int { items[i] } }
This program shows a protocol with an associated type Number. Two structs conform to it, one for Int and one for Double. Each sums two numbers of its type.
protocol Summable { associatedtype Number func sum(_ a: Number, _ b: Number) -> Number } struct IntSummer: Summable { func sum(_ a: Int, _ b: Int) -> Int { return a + b } } struct DoubleSummer: Summable { func sum(_ a: Double, _ b: Double) -> Double { return a + b } } let intSummer = IntSummer() print(intSummer.sum(3, 4)) let doubleSummer = DoubleSummer() print(doubleSummer.sum(2.5, 3.5))
Protocols with associated types cannot be used as types directly without specifying the associated type.
Use some ProtocolName or generics to work with protocols with associated types.
Protocols with associated types let you write flexible blueprints with placeholder types.
The actual type is decided by the conforming type.
This helps create reusable and type-safe code.
Practice
What is the main purpose of a protocol with an associated type in Swift?
Solution
Step 1: Understand what associated types do
Associated types act as placeholders in protocols, letting conforming types specify the actual type.Step 2: Compare options
To define a blueprint with a placeholder type that conforming types specify correctly describes this flexibility. Options A, B, and D are incorrect because protocols don't fix types, can't have stored properties, and don't enable class inheritance.Final Answer:
To define a blueprint with a placeholder type that conforming types specify -> Option DQuick Check:
Associated type = Placeholder type in protocol [OK]
- Thinking associated types fix the type for all conformers
- Confusing protocols with classes regarding stored properties
- Believing protocols support multiple inheritance
Which of the following is the correct syntax to declare an associated type named Item inside a protocol?
Solution
Step 1: Recall syntax for associated types
In Swift, the keyword to declare an associated type inside a protocol isassociatedtype.Step 2: Check options
protocol Example { associatedtype Item } usesassociatedtype Item, which is correct. protocol Example { typealias Item } uses outdatedtypealiaswhich is invalid here. Options C and D are incorrect syntax.Final Answer:
protocol Example { associatedtype Item } -> Option AQuick Check:
Use 'associatedtype' keyword for associated types [OK]
- Using 'typealias' instead of 'associatedtype' inside protocols
- Trying to declare associated types as variables
- Omitting the keyword entirely
Consider the following Swift code:
protocol Container {
associatedtype Item
func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
var items = [Int]()
mutating func append(_ item: Int) {
items.append(item)
}
var count: Int { items.count }
subscript(i: Int) -> Int { items[i] }
}
var stack = IntStack()
stack.append(10)
stack.append(20)
print(stack[1])What will be the output?
Solution
Step 1: Understand the Container protocol and IntStack
The protocol requires an associated type Item and methods to append, count, and subscript. IntStack conforms with Item as Int.Step 2: Trace the code execution
We append 10, then 20 to the stack. The stack items array is [10, 20]. Accessing stack[1] returns the second element, which is 20.Final Answer:
20 -> Option BQuick Check:
stack[1] = 20 [OK]
- Confusing index 1 with index 0
- Expecting a compilation error due to associated type
- Assuming append doesn't work because of protocol
Identify the error in this Swift code snippet:
protocol DataSource {
associatedtype Data
func fetch() -> Data
}
struct IntSource: DataSource {
typealias Data = Int
func fetch() -> String {
return "Hello"
}
}Solution
Step 1: Analyze the protocol and struct
The protocol DataSource has an associated type Data and requires fetch() returning Data.Step 2: Check IntSource conformance
IntSource specifiestypealias Data = Intbut implements fetch() returning String, which does not match the associated type Data.Step 3: Identify mismatch
Data is explicitly set to Int, but fetch() returns String, this is a mismatch causing a compile error.Final Answer:
fetch() return type does not match associated type Data -> Option AQuick Check:
Return type must match associated type [OK]
- Forgetting to specify associated type explicitly
- Assuming return type can differ from associated type
- Thinking structs can't conform to such protocols
You want to create a generic function printFirstItem that accepts any type conforming to the Container protocol below and prints its first item. Which is the correct way to write this function?
protocol Container {
associatedtype Item
var count: Int { get }
subscript(i: Int) -> Item { get }
}Solution
Step 1: Understand protocol with associated type usage
Protocols with associated types cannot be used as concrete types directly, soContaineralone is invalid as a parameter type.Step 2: Analyze options
func printFirstItem(_ container: C) { print(container[0]) } uses a generic parameter constrained toContainer, which is correct. func printFirstItem(_ container: Container) { print(container[0]) } tries to use protocol as a type directly, which is invalid. func printFirstItem(_ container: Container<Item>) { print(container[0]) } uses invalid syntax. func printFirstItem<C>(_ container: C) where C: Container, C.Item == String { print(container[0]) } adds an extra constraint onItembeing String, which is unnecessary here.Final Answer:
func printFirstItem(_ container: C) { print(container[0]) } -> Option CQuick Check:
Use generics with protocol constraints for associated types [OK]
- Trying to use protocol with associated type as a concrete type
- Incorrect generic syntax
- Adding unnecessary constraints
Ready to prove it?
Pass the test and this pattern moves unknown
