In my Domain module I am defining a protocol Assignment, TimeLog and AssignmentTimeLog.
When defining a concrete implementation I want to use generics to conform to the AssignmentTimeLog protocol. To do so I am constraining my generic A, T parameters to be of type Domain.Assignment and Domain.TimeLog. Why does this not satisfy the protocol requirements? I want to understand the logic of what's going on.
// Domain Module
public protocol AssignmentTimeLog {
var assignment: Assignment { get }
var timeLog: TimeLog { get }
}
// My attempt to create an implementation trows an error
// Error:
// Type 'AssignmentTimeLog<A, T>' does not conform to protocol 'AssignmentTimeLog'
import Domain
struct AssignmentTimeLog<A, T>:
Domain.AssignmentTimeLog where A: Domain.Assignment, T: Domain.TimeLog {
var assignment: A
var timeLog: T
}
For Context: The reason for using generics is that later I want to define an extension on AssignmentTimeLog where A & T also implement another protocol. This provides additional functionality without additional code. Concrete types implement the Domain protocols as well as those additional protocols.
I have tried to figure out this by reading the documentation and multiple blogs. But I can't seem to zone in on the exact issue/gap in understanding that I have.
CodePudding user response:
The protocol says a different thing from what your implementation says.
Fact 1
According to the protocol this getter
var assignment: Assignment { get }
can return any value conforming to Assignment
.
Fact 2
On the other hand your implementation here
var assignment: A
says that assignment
will contain a value of a specific type A
(which happens to conform to Assignment
).
These are 2 very different statements.
The fix
Here's an easy fix
protocol AssignmentTimeLog {
associatedtype A: Assignment
associatedtype B: TimeLog
var assignment: A { get }
var timeLog: B { get }
}
struct MyAssignmentTimeLog<A, T>: AssignmentTimeLog where A: Assignment, T: TimeLog {
var assignment: A
var timeLog: T
}