gpt4 book ai didi

ios - 转换作为数组的泛型类型时出现问题

转载 作者:行者123 更新时间:2023-11-29 05:23:30 24 4
gpt4 key购买 nike

我已经构建了一个通用存储库,它返回我请求的资源。这工作得很好,直到我尝试通过将多个 fetch 调用包装到 DispatchGroup 中来执行分组请求。存储库是一个通用类,指示返回类型。

我将每个单独提取的响应存储到字典中,一旦所有这些都准备好,我就会将字典转换为预期的返回类型。

当泛型的类型为 [Something](即 T == [Something])时,就会出现问题

    public typealias RepoCompletion<T: Codable> = (Result<T?, Error>) -> Void

public func fetch<T: Entity>(_ resources: [FetchResource<T>], completion: @escaping RepoCompletion<T>) {
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
let group = DispatchGroup()
let valueSyncQueue = DispatchQueue(label: "Repo.ValueSync")
var values = [String: T]()

for resource in resources {
group.enter()
self.localDataSource.fetch(resource) { result in
switch result {
case .success(let value):
if let value = value {
valueSyncQueue.sync {
values[resource.description] = value
}
}

case .failure(_): break
}

group.leave()
}
}

group.wait(timeout: .now() + 10)
let flattenedValues = resources.compactMap({ values[$0.description] }).flatMap({ $0 })
completion(.success(flattenedValues))
}
}

上面的代码无法编译。错误显示 Member 'success' in 'Result<_?, Error>' produces result of type 'Result<Success, Failure>', but context expects 'Result<_?, Error>' .我认为问题的出现是因为泛型类型是 [] 并且编译器需要帮助。

调试时查看类型:

(lldb) po type(of: resources.compactMap({ values[$0.description] }))
Swift.Array<Swift.Array<Schedule>>

(lldb) po type(of: resources.compactMap({ values[$0.description] }).flatMap({ $0 }))
Swift.Array<Schedule>

(lldb) po type(of: flattenedValues)
Swift.Array<Swift.Array<Schedule>>

我不明白为什么表达 let flattenedValues = resources.compactMap({ values[$0.description] }).flatMap({ $0 })一旦评估,左侧和右侧就有不同的类型:S

假设 T == [时间表]。我预计values为[字符串:[时间表]]。那么当 .compactMap我期望 [[Schedules]] 的结果,最后是 .flatMap返回[时间表](即T)。但我遗漏了一些东西或者我不明白。

如果我尝试帮助编译器并强制将 flattenedValues 转换为! T,返回时崩溃了

Could not cast value of type 'Swift.Array' (0x1058073b0) to 'Schedule' (0x1044ac928). 2019-10-17 09:48:14.585362+0200 Chicisimo[86448:2426001] Could not cast value of type 'Swift.Array' (0x1058073b0) to 'Schedule' (0x1044ac928).

我不太明白,因为 T类型为[Schedule]且不是 Schedule 类型.

任何帮助将不胜感激!谢谢!

最佳答案

您收到此错误是因为您正在尝试创建 Result数组为T ,当您完成时,期望出现一个 T值。

values: [String: T]建立一个列表 T在你的 for 循环中:

for resource in resources {
// here value is a T
values[resource.description] = value
}

扁平值变量是 values 的紧凑映射的结果字典

let flattenedValues = resources.compactMap({ values[$0.description] }).flatMap({ $0 })

这意味着此时 flattenedValues 的类型是 [T] .

完成 ( (Result<T?, Error>) -> Void ) 期望 Result具有 T 类型的单个值,但您正在尝试使用数组( [T] )来解决它。这就是您收到此错误的原因。

解决方案:

据我了解,您希望从多个资源( FetchResource )获取实体,这意味着您可能希望始终返回实体数组( [T] )。

如果是这样,您只需更改您的 RepoCompletion到数组:[T] 。这看起来像这样:

// change RepoCompletion<T> to RepoCompletion<[T]>
public func fetch<T: Entity>(_ resources: [FetchResource<T>], completion: @escaping RepoCompletion<[T]>) {
// ...
}

关于ios - 转换作为数组的泛型类型时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58428281/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com