Sorry for all these protocol mess. I provide it for the sake of code completeness. The question is actually about the last chunk of the code at the bottom.
protocol Edgedable: Hashable {
associatedtype Edge: Destinationable
var edges: Set<Edge> { get set }
}
protocol Destinationable: Hashable {
associatedtype D: Hashable
var destination: D { get set }
}
class Graph<Node: Edgedable>: ExpressibleByDictionaryLiteral {
typealias Edge = Node.Edge
typealias D = Edge.D
private var storage: [D: Node]
init(_ tuples: [(D, Node)]) {
self.storage = .init(uniqueKeysWithValues: tuples)
// Some PostInit code here
}
required convenience init(dictionaryLiteral elements: (D, Node)...) {
self.init(elements)
}
}
extension Graph: ExpressibleByArrayLiteral where D == Int {
required convenience init(arrayLiteral elements: Node...) {
self.init(Array(zip(0..., elements)))
}
}
I choose a standard approach here: via extension. It looks like exactly what I need. That is the class implements the protocol only in the case of D == Int
But the code doesn't compile:
'required' initializer must be declared directly in class 'Graph' (not in an extension)
Initializer requirement 'init(arrayLiteral:)' can only be satisfied by a 'required' initializer in the definition of non-final class 'Graph'
Okey, I can declare it directly in class, exactly like I did with another init (and another corresponding protocol). But how to set the constraint!?
class Graph<Node: Edgedable>: ExpressibleByDictionaryLiteral, ExpressibleByArrayLiteral where Node.Edge.D == Int {
This is not correct. This declaration has a different meaning. Not that I'm trying to achieve.
I don't know of a way to achieve this without making Graph final
. If you do make it final
, however, it will work fine as long as you remove required
( required
doesn't mean anything if there can't be subclasses):
extension Graph: ExpressibleByArrayLiteral where D == Int {
convenience init(arrayLiteral elements: Node...) {
self.init(Array(zip(0..., elements)))
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.