Во-первых, я бы порекомендовал вам прочитать Empowering Extensions in Swift 2: Protocols, Types and Subclasses (Xcode 7 beta 2). (Поскольку для бета-версии 2 было несколько незначительных изменений)
Назад к проблеме. Для Array
:
extension Array where Element: JsonSerializable {
var json: String { ... }
}
[1, 2, 3].json // Valid
[true, false].json // Invalid; `Bool` doesn't conform to `JsonSerializable`.
словарь немного сложнее, потому что, как сказано в упомянутой статье:
Действующие правила расширения универсального типа, таким образом, является то, что тип который ссылается после где ключевое слово должно быть классом или протоколом .
Поэтому вы не можете определить, что Key
из Dictionary
должен быть String
. Обходной дано в статье определить StringType
протокол:
protocol StringType {
var characters: String.CharacterView { get }
}
extension String: StringType {}
Теперь для словаря расширения:
extension Dictionary where Key: StringType, Value: JsonSerializable {
var json: String { ... }
}
["A": 1, "B": 2].json // Valid
[1: "1", 2: "2"].json // Invalid; `Int` doesn't conform to `StringType`.
["A": true, "B": false].json // Invalid; `Bool` doesn't conform to `JsonSerializable`.
В качестве альтернативы, вы можете создать свой собственный JsonArray
и JsonDictionary
типов, которые бы должны быть подкреплены Array
или Dictionary
соответственно:
struct JsonArray<Element: JsonSerializable> {
private var array: [Element]
...
}
extension JsonArray: ArrayLiteralConvertible {
init(arrayLiteral elements: Element...) {
self.init(array: elements)
}
}
struct JsonDictionary<Value: JsonSerializable> {
private var dictionary: [String: Value]
...
}
extension JsonDictionary: DictionaryLiteralConvertible {
init(dictionaryLiteral elements: (String, Value)...) {
var temp = [String: Value]()
for (key, value) in elements {
temp[key] = value
}
self.init(dictionary: temp)
}
}
let array: JsonArray = [1, 2, 3]
let dictionary: JsonDictionary = ["A": 1, "B": 2]
Вы используете Swift 2? Это будет возможно, если вы. – ABakerSmith
есть. Как мне пойти ti –
кажется, что это часть этого предложения https://github.com/apple/swift-evolution/blob/master/proposals/0157-recursive-protocol-constraints.md –