Seeing in the Apple doc that the Task is defined as:
@frozen struct Task<Success, Failure> where Success : Sendable, Failure : Error
I've seen a number of code online where people add extensions to Task with constraint like:
extension Task where Failure == Error {}
and/or
extension Task where Success == Sendable {}
For example, the code here extends Task with the constraint Failure == Error. Given that Task is defined with constraint Failure: Error I wonder what's the specific need for adding Failure == Error?
Thanks!
A type satisfies the
: Errorconstraint if it conforms toError. For example, this type:However,
MyErrordoes not satisfy an== Errorconstraint, because the only type that satisfies this constraint isErroritself. It says "equal to"Error, after all :)You can apply the same logic to
Sendable.The versions of
Task.initandTask.detachedthat take a throwing closure, andrelayResultin your linked code, all requires== Error, because they all create tasks from a throwing closure.You don't know what specific type of
Errora throwing closure is going to throw. The best you know is it throwsError. Therefore, these methods can only create a task whose failure type is exactlyError. They cannot create a task whose failure type is, say,MyError,because the throwing closure can throw
AnotherError.But let's say the "throwing other types of errors" problem is magically handled somehow, this
== Erroralso serves as an easy way for the compiler to infer theFailuretype when you call these methods. You don't need to write the type of error the task can throw explicitly, like I did above.I can't think of when you would use exactly
Sendableas theSuccesstype off the top of my head though. That doesn't seem very useful.Sendabledoesn't have any syntactic requirements, so it is functionally the same as using exactlyVoid(aka(), and also conforms toSendable) as theSuccesstype, to indicate "this task just "finishes" and has no result". If I were to choose, I would definitely chooseVoidinstead ofSendableto express this idea.