我正在与我写一个应用程序的JSON解析部分的问题,使用的通用typealias。我在下面的游乐场中写了一个快速示例来说明这个问题。我有一个解析器类型的协议和符合它的解析器对象的集合。除了最后一行,一切都完美无瑕。编译器在确定泛型应该是什么类时遇到了问题,我不确定这是我犯的错误还是编译器本身的错误。协议以扩展
错误是由该示例的最后一行生产中记载:
在这个例子中我做的最后几行词典的扩展,但在我的实际应用中,我使用RxSwift,并且该扩展是可观察到的,因为我尝试写:
API.someNetworkRequest().parsed().subscribeNext() { thing in }
这个错误没有关系,虽然RxSwift。
另外要注意,我已经尝试使用“作为!”以及其他一些尝试让编译器了解我想要的泛型约束是什么类型的方法。如果我可以直接编写parsed()并直接提供通用约束条件,但我不能这样做,因为它是一个函数并产生错误“无法显式地专用通用函数”。
protocol ParserType {
typealias ParsedObjectType
init()
func parse(object: AnyObject) throws -> ParsedObjectType
}
struct Dog {
var name: String?
}
class DogParser: ParserType {
required init() { }
func parse(object: AnyObject) throws -> Dog {
return Dog()
}
}
struct PaginationContext {
var nextPageLink: String?
}
class PaginatedParser<T where T: ParserType>: ParserType {
required init() { }
func parse(object: AnyObject) throws -> ([T.ParsedObjectType], PaginationContext?) {
// some array from json object
let jsonArray = ["test", "test", "test"]
let childParser = T()
let parsedDogs: [T.ParsedObjectType] = jsonArray.flatMap() {
do {
return try childParser.parse($0 as! AnyObject)
} catch {
return nil
}
}
let pagination = PaginationContext()
return (parsedDogs, pagination)
}
}
// This works perfectly
let paginatedParser = PaginatedParser<DogParser>()
let thing = [String: AnyObject]()
let parsedData = try! paginatedParser.parse(thing as! AnyObject)
extension Dictionary {
func parsed<T where T: ParserType>() -> ([T.ParsedObjectType], PaginationContext?) {
let paginatedParser = PaginatedParser<T>()
return try! paginatedParser.parse(self as! AnyObject)
}
}
// This won't. The compiler can't figure out that it needs to use DogParser.
let thing2 = [String: AnyObject]()
let result: ([DogParser.ParsedObjectType], PaginationContext?) = thing2.parsed()
这结束了完美的工作。我尝试将参数类型作为参数传递,但认为它对于未使用的内部参数名称看起来很严重,而且必须可以让它在没有参数的情况下工作。使用下划线是我没有想到的。谢谢! – pmick