我已经开发了这种通用方法来执行请求:
func executeRequest<T, S, E>(_ request : RequestBuilder<T>,
map: (@escaping (T) -> S)) -> RepositoryResult<S, E> {
return RepositoryResult().doTask { result in
request.execute{ (response, error) in
// do some stuff
result.notifySuccess(value: map(body))
}
}
我的地图函数是在具有通用类型的子类中定义的:
class BaseMapper<R, U> {
class func transform(_ dataModel:R) -> U {
fatalError("Override this method")
}
// other generic methods
}
class HomeMapper:BaseMapper<HomeDTO, Home> {
override class func transform(_ dataModel: HomeDTO) -> Home {
return Home(customerFirstName: dataModel.customerFirstName,
balance: MoneyMapper.transform(dataModel.balance),
accounts: AccountSummaryMapper.listTransform(dataModel.summaries))
}
}
如果我调用请求执行程序方法,则直接传递map函数,如下所示:
func getHomeInfo() -> RepositoryResult<Home, HomeError> {
return executeRequest(HomeAPI.getMyHomeWithRequestBuilder(), map: HomeMapper.transform)
}
我相信Swift编译器会崩溃,因为它会返回几个随机错误:“细分错误:11”。否则,如果我调用指定“ S”返回类型的方法,它将起作用:
func getHomeInfo() -> RepositoryResult<Home, HomeError>{
return executeRequest(HomeAPI.getMyHomeWithRequestBuilder(), map: { (homeDTO) -> Home in
HomeMapper.transform(homeDTO)
})
}
此外,使用不继承自BaseMapper的Mapper并直接传递函数,它也可以工作。我不明白的另一件事是RxSwift有一个map函数,可以使用我的第一个选项调用它...
为什么Swift编译器无法推断“ S”类型?为什么Swift编译器崩溃了,却无法分辨哪一行崩溃了,为什么?
答案 0 :(得分:0)
我找到了一个解决方案:associatedtypes
protocol Mappable {
associatedtype T
associatedtype S
static func transform(_ dataModel:T) -> S
}
class MapperHome : Mappable {
static func transform(_ dataModel: HomeDTO) -> Home {
return Home(customerFirstName: dataModel.customerFirstName,
balance: MoneyMapper.transform(dataModel.balance),
accounts: AccountSummaryMapper.listTransform(dataModel.summaries))
}
}
func getHomeInfo() -> RepositoryResult<Home, HomeError>{
return executeRequest(HomeAPI.getMyHomeWithRequestBuilder(), map: MapperHome.transform)
}
我不明白为什么这段代码会编译,并且使用协议实现的继承实例却没有...我不知道这是编译器错误还是我的错。