我有以下协议及其扩展名
public protocol RESEndpointReachable: CustomDebugStringConvertible
{
associatedtype EndpointType: RESEndpointReachable
// MARK: - Properties
/// The name of the endpoint as defined in the REST URI.
var name: String { get }
/// An array of possible next endpoints that this endpoint can reach. E.g account's next endpoints would be authenticate and unauthenticate.
var nextPossibleEndpoints: [EndpointType] { get }
// MARK: - Ability
/// Used to process the endpoint.
func processRequest(request: RERequest)
/// Processes the next endpoint that matches the name `name`. Expects an endpoint with the name `name` to exist in `nextPossibleEndpoints`.
func processNextEndpointWithName(name: String, request: RERequest)
}
public extension RESEndpointReachable
{
// MARK: - CustomDebugStringConvertible
public var debugDescription: String {
return name
}
// MARK: - RESEndpointReachable
var nextPossibleEndpoints: [EndpointType] {
return []
}
public func processRequest(request: RERequest)
{
// Check all possible endpoints are being processed
if let nextEndpoint = nextPossibleEndpoints.first
{
fatalError("Unhandled endpoint \(nextEndpoint).")
}
}
public func processNextEndpointWithName(name: String, request: RERequest)
{
// Get the next endpoint that matches the specified name
let nextEndpoints = nextPossibleEndpoints.filter { $0.name == name }
if nextEndpoints.count > 1
{
fatalError("Multiple next endpoints found with the name '\(name)'.")
}
guard let nextEndpoint = nextEndpoints.first else
{
fatalError("No next endpoint with the name '\(name)'.")
}
// Process the next endpoint
nextEndpoint.processRequest(request)
}
}
在构建时,行associatedtype EndpointType: RESEndpointReachable
出现以下错误:Type may not reference itself as a requirement
。但据我所知,这就是你在Swift中使用相关类型的方式。
正如您可能已经猜到的那样,我总是希望将EndpointType
最终设置为继承自RESEndpointReachable
的类型。
答案 0 :(得分:4)
Swift团队将此功能称为“递归协议约束”,并且该路线图将在未来版本的Swift中添加。有关此计划功能和其他计划功能的详细信息,请查看Swift团队'Completing Generics' manifesto。
答案 1 :(得分:1)
是的,swift不行。协议不能将其自身用作类型约束。一种解决方案是声明一个额外的协议 RESEndpointReachable 本身将采用并约束 RESEndpointReachable 到该超级协议。
我采用了Neuburg M.的书“ iOS 10编程基础与Swift ”中的示例(请参阅第194页)
非法的例子:
1 protocol Flier {
2 associatedtype Other : Flier
3 func flockTogetherWith(_ f: Other)
4 }
5
6 struct Bird : Flier {
7 func flockTogetherWith(_ f: Bird) {}
8 }
解决方案:
1 protocol Superflier {}
2 protocol Flier: Superflier {
3 associatedtype Other : Superflier
4 func flockTogetherWith(_ f: Other)
5 }
6
7 struct Bird : Flier {
8 func flockTogetherWith(_ f: Bird) {}
9 }
干杯