Swift 扩展到具有通用类型约束的 Observable
Swift Extension to Observable with Generic Type Constraint
我正在尝试为 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]
}
问题
您不能在不指定通用值的 模型类型 的情况下将扩展约束到包含通用值的 模型类型。
您只能根据 associatedtype
限制协议,或根据扩展签名的泛型限制泛型。因此 T
不被识别,因为 none 的协议或通用声明它。
解决方案
因此,请记住我上面所说的,模型类型 需要在扩展上下文中完全定义。 但是不满足我们的要求等等,我们希望它是通用的!
Then we do not need a Model Type, we need a protocol!
我们有两个模型类型(ApiResponse 和 ItemsContainer),我们需要知道它们的通用类型,因此我们需要两个协议他们每个人。
ApiResponse
让我们创建一个名为 ApiResponseProtocol
public protocol ApiResponseProtocol {
associatedtype Model
var data: Model? { get }
}
太棒了,associatedtype Model
将扮演我们的角色,作为对象上 ApiModel
的通用值。让我们让 ApiResponse
符合 ApiResponseProtocol
public struct ApiResponse<ApiModel>: ApiResponseProtocol {
public let data: ApiModel?
}
Generic 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 {}
我正在尝试为 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]
}
问题
您不能在不指定通用值的 模型类型 的情况下将扩展约束到包含通用值的 模型类型。
您只能根据 associatedtype
限制协议,或根据扩展签名的泛型限制泛型。因此 T
不被识别,因为 none 的协议或通用声明它。
解决方案
因此,请记住我上面所说的,模型类型 需要在扩展上下文中完全定义。 但是不满足我们的要求等等,我们希望它是通用的!
Then we do not need a Model Type, we need a protocol!
我们有两个模型类型(ApiResponse 和 ItemsContainer),我们需要知道它们的通用类型,因此我们需要两个协议他们每个人。
ApiResponse
让我们创建一个名为 ApiResponseProtocol
public protocol ApiResponseProtocol {
associatedtype Model
var data: Model? { get }
}
太棒了,associatedtype Model
将扮演我们的角色,作为对象上 ApiModel
的通用值。让我们让 ApiResponse
符合 ApiResponseProtocol
public struct ApiResponse<ApiModel>: ApiResponseProtocol {
public let data: ApiModel?
}
Generic 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 {}