swift - 使用泛型类型约束对 Observable 进行 Swift 扩展
问题描述
我正在尝试向 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
您仅在扩展签名上基于它们的 s 或基于泛型类型的泛型来约束协议。因此T
无法识别,因为没有任何协议或泛型声明它。
解决方案
因此,记住我上面所说的,模型类型需要在扩展上下文中完全定义。但是等等,这不能满足我们的要求,我们希望它是通用的!
那么我们不需要模型类型,我们需要一个协议!
我们有两个模型类型(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?
}
这里的泛型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 {}
推荐阅读
- php - 如何在短代码中获取帖子网址
- javascript - javascript selection text change font size code editor
- c# - 将类实例保存到文件并从另一个项目访问它
- css - 使用数据库中的数据制作可滚动的引导表
- php - Laravel 将数据库整数转换为字符串
- java - 如何在 install4j 中禁用箭头屏幕导航
- android - Angular 4 逗号不适用于平板电脑 android 键盘
- firefox - svg.node.getScreenCTM() 在 Firefox 中不可用
- amazon-web-services - 修改表后从 AWS AURORA 触发 AWS lambda
- ionic-framework - ion-footer 中的 ion-fab 总是在 ion-content 下