符合协议时类型化声明的冗余重复第2部分

问题描述

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 }
    }
}

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

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

为什么会这样?什么递归?

解决方法

我不确定什么是递归,但您应该避免在 protocol extensions 中声明类型别名并改用相同类型的常量:

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 }
    }
}

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

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 }
    }
}

可能就够了。