ios - Swift:非泛型结构中的泛型初始化
问题描述
好的,我将尝试用一个最小的可行示例向您解释我想要得到什么:我想要一个这样的结构:
struct MyStruct {
let aBool: Bool
let aInt: Int
let aHashable: Hashable?
}
但当然不能这样做,因为:
协议 'Hashable' 只能用作通用约束,因为它具有 Self 或关联的类型要求
这很好。我可以通过这种方式得到我想要的:
struct MyStruct<T> where T: Hashable {
let aBool: Bool
let aInt: Int
let aHashable: T?
}
但我希望我的结构以这种方式有两个初始化:
struct MyStruct<T> where T: Hashable {
let aBool: Bool
let aInt: Int
let aHashable: T?
init(aBool: Bool, aInt: Int) {
self.init(aBool: aBool, aInt: aInt, aHashable: nil)
}
init(aHashable: T?) {
self.init(aBool: false, aInt: 0, aHashable: aHashable)
}
private init(aBool: Bool, aInt: Int, aHashable: T?) {
self.aBool = aBool
self.aInt = aInt
self.aHashable = aHashable
}
}
如果我尝试像这样初始化结构:
let myStruct = MyStruct(aBool: true, aInt: 10)
我收到一个错误:
无法推断通用参数“T”
问题是,即使我将结构转换为非通用结构(带有几个通用 init):
struct MyStruct {
let aBool: Bool
let aInt: Int
let aHashable: T?
init(aBool: Bool, aInt: Int) {
self.init(aBool: aBool, aInt: aInt, aHashable: nil)
}
init<T>(aHashable: T?) where T: Hashable {
self.init(aBool: false, aInt: 0, aHashable: aHashable)
}
private init<T>(aBool: Bool, aInt: Int, aHashable: T?) where T: Hashable {
self.aBool = aBool
self.aInt = aInt
self.aHashable = aHashable
}
}
我仍然收到错误消息。这次在let aHashable: T?
存储的属性上:
使用未声明的类型“T”
得到我想要的东西的正确方法是什么?谢谢你。
解决方案
在这种T
情况下,您想要的是Never
,因为它永远不会有值。要定义这种初始化,您需要将其限制在这样的扩展中:
extension MyStruct where T == Never {
init(aBool: Bool, aInt: Int) {
self.init(aBool: aBool, aInt: aInt, aHashable: nil)
}
}
IMO,Swift 也应该允许这样做:
init(aBool: Bool, aInt: Int) where T == Never {...}
但这不是目前合法的 Swift。你必须把它放在一个扩展中。这只是一个语法问题。
为了完整起见,这里是完整的代码:
struct MyStruct<T> where T: Hashable {
let aBool: Bool
let aInt: Int
let aHashable: T?
init(aHashable: T?) {
self.init(aBool: false, aInt: 0, aHashable: aHashable)
}
private init(aBool: Bool, aInt: Int, aHashable: T?) {
self.aBool = aBool
self.aInt = aInt
self.aHashable = aHashable
}
}
extension MyStruct where T == Never {
init(aBool: Bool, aInt: Int) {
self.init(aBool: aBool, aInt: aInt, aHashable: nil)
}
}
let myStruct = MyStruct(aBool: true, aInt: 10)
推荐阅读
- django - 如何使用 Django Rest 框架通过 Javascript 文件调用 API
- javascript - 使用 NodeJS 和 Javascript 将输出保存到每个用户会话的文件
- node.js - Gatsby + Reach 路由器:控制客户端路由路径的最佳模式
- python - Instagram Private API 更改您的简历
- python-3.x - 使用 Tensorflow 模型优化修剪后保存的模型文件大小相同
- node.js - Redis:“auth”命令的参数数量错误
- python - ScannerError:扫描下一个令牌时
- swift - 什么是在 Swift 中构建 CLI 应用程序的好方法或常用方法
- node.js - 类型错误:cloudinaryStorage 不是函数
- hive - 如何在 SparkSQL 上获取诸如 totalNumberFiles、totalFileSize、maxFileSize 等 FileSystemStats?