Swift 5 泛型场景下同类型属性赋值出现编译错误问题求助
问题解决方案
错误根因
- Swift泛型具备不变性:即使泛型参数存在继承关系,泛型类型本身不存在继承关系,
SQS_Table<Project>和SQS_Table<SQS_Record>属于完全不同的类型,无法直接赋值 - 原代码中
SQS_Record的table属性默认推断为SQS_Table<SQS_Record>?类型,而SQS_Table的newRecord方法中要赋值的self是对应具体子类的泛型类型,二者类型不匹配触发编译错误
修正方案(类型安全版,无运行时开销)
通过泛型绑定记录和表的对应关系,完全兼容你预期的使用方式:
// 定义记录基类,泛型参数对应当前记录所属的表类型 class SQS_Record<TableType> { var table: TableType? = nil } // 表类泛型约束绑定记录的表类型为自身类型 class SQS_Table<RecordType: SQS_Record<SQS_Table<RecordType>>> { func newRecord() -> RecordType { let new = RecordType() new.table = self // 编译正常 return new } } // 业务定义自定义记录类,和你的预期写法完全对齐 class Project: SQS_Record<SQS_Table<Project>> { var name: String = "" } // 使用方式和你预期完全一致 let projectsTbl = SQS_Table<Project>() let item = projectsTbl.newRecord() // 自动推断为Project类型
简化方案(Swift 5.7+支持)
如果不需要强类型约束表的具体泛型类型,可以用存在类型简化写法:
// 定义表的公共协议 protocol SQS_TableProtocol {} class SQS_Record { // 用存在类型声明可存储任意符合协议的表实例 var table: (any SQS_TableProtocol)? = nil } class SQS_Table<RecordType: SQS_Record>: SQS_TableProtocol { func newRecord() -> RecordType { let new = RecordType() new.table = self // 编译正常 return new } } // 业务代码无需额外修改,完全对齐你的预期 class Project: SQS_Record { var name: String = "" } let projectsTbl = SQS_Table<Project>() let item = projectsTbl.newRecord()
内容的提问来源于stack exchange,提问作者Alex778801
相关产品推荐
相关产品推荐

