我正在尝试向Observable添加扩展名。 代码如下:
extension Observable where Element == ApiResponse<ItemsContainer<T>>, T:Codable
我收到以下异常:Use of undeclared type T
。
因此,这显然行不通。
唯一缺少的是约束ItemsContainer
内部的泛型以符合Codable
。
可能就像语法问题一样简单,或者我对泛型还不够好。任何帮助表示赞赏!
编辑:给出一个想法-ApiResponse和ItemsContainer看起来像这样
public struct ApiResponse<ApiModel> {
public let data: ApiModel?
}
struct ItemsContainer<Items>: Codable where Items: Codable {
let items: [Items]
}
答案 0 :(得分:0)
如果不指定通用值的 Model Type ,则不能将扩展约束为保存通用值的 Model Type 。
您只能根据协议的associatedtype
约束协议,或者根据扩展名对它们的通用类型进行约束。因此T
无法识别,因为没有协议或通用声明。
因此,请记住我在上面所说的内容,需要在扩展上下文中完全定义 Model Type 。 但是等不满足我们的要求,我们希望它是通用的!
然后我们不需要模型类型,我们需要协议!
我们有两种模型类型( ApiResponse 和 ItemsContainer ),我们需要了解其通用类型,因此每种模型都需要两种协议。
让我们创建一个名为ApiResponseProtocol
public protocol ApiResponseProtocol {
associatedtype Model
var data: Model? { get }
}
很酷,associatedtype Model
将充当对象上ApiModel
的通用值。让我们使ApiResponse
符合ApiResponseProtocol
public struct ApiResponse<ApiModel>: ApiResponseProtocol {
public let data: ApiModel?
}
此处的通用ApiModel
在协议中可以定义为Model
。
ItemsContainer
的后续步骤相同
public protocol ItemsContainerProtocol {
associatedtype Item
var items: [Item] { get }
}
public struct ItemsContainer<Items>: Codable, ItemsContainerProtocol where Items: Codable {
public let items: [Items]
}
现在,由于我们可以从协议(associatedtypes
)访问每个泛型类型,因此输出将变成这样:
// This would be for example ApiResponse<ItemsContainer<Model>> where Model is a Model Type conforming to Codable
extension Observable where Element: ApiResponseProtocol, Element.Model: ItemsContainerProtocol, Element.Model.Item: Codable {}