符合协议时类型别名声明的冗余重复(第 2 部分)

Rom*_*man 5 protocols type-alias swift

protocol Destinationable: Hashable {
    associatedtype D: Hashable
    var destination: D { get }
}

protocol Graph {
    associatedtype Edge: Destinationable
    subscript(node: D) -> Set<Edge>! { get set }
}

extension Graph {
    typealias D = Edge.D
}

struct UndirectedGraph<Edge: Destinationable>: Graph {
    typealias D = Edge.D // Why should we again declare this typealias!?
    
    private var storage: [D: Set<Edge>]
    
    subscript(node: D) -> Set<Edge>! {
        get { storage[node] }
        set { storage[node] = newValue }
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效。但是,如果我删除typealias D = Edge.D结构中的重新声明,则会出现与下标相关的编译错误:

不支持引用类型别名“D”的“UndirectedGraph”类型的递归

为什么会发生?什么递归???

And*_*ver 1

我不确定什么是递归,但您应该避免在协议扩展中声明类型别名并使用相同类型的约束:

protocol Destinationable: Hashable {
    associatedtype D: Hashable
    var destination: D { get }
}

protocol Graph {
    associatedtype D
    associatedtype Edge: Destinationable where D == Edge.D
    subscript(node: D) -> Set<Edge>! { get set }
}

struct UndirectedGraph<Edge: Destinationable>: Graph {
    private var storage: [D: Set<Edge>]
    
    subscript(node: Edge.D) -> Set<Edge>! {
        get { storage[node] }
        set { storage[node] = newValue }
    }
}
Run Code Online (Sandbox Code Playgroud)

编译得很好,但在你的情况下:

protocol Destinationable: Hashable {
    associatedtype D: Hashable
    var destination: D { get }
}

protocol Graph {
    associatedtype Edge: Destinationable
    subscript(node: Edge.D) -> Set<Edge>! { get set }
}

struct UndirectedGraph<Edge: Destinationable>: Graph {
    private var storage: [Edge.D: Set<Edge>]
    
    subscript(node: Edge.D) -> Set<Edge>! {
        get { storage[node] }
        set { storage[node] = newValue }
    }
}

Run Code Online (Sandbox Code Playgroud)

可能就足够了。