ios - Swift:非通用结构中的通用初始化

标签 ios swift generics

好的,我会试着用一个最小可行的例子向你解释我想要得到的东西:我想要一个这样的结构:

struct MyStruct {
    let aBool: Bool
    let aInt: Int
    let aHashable: Hashable?
}

但当然这是不可能的,因为:

Protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements



这很好。我可以通过这种方式得到我想要的:
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)

我收到一个错误:

Generic parameter 'T' could not be inferred



问题是,即使我将结构转换为非通用结构(带有几个通用初始化):
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?存储属性:

Use of undeclared type 'T'



获得我想要的东西的正确方法是什么?谢谢你。

最佳答案

T在这种情况下,您想要的是 Never ,因为它永远不会有值。要定义这种 init,您需要将它限制在这样的扩展中:

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)

关于ios - Swift:非通用结构中的通用初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59291061/

相关文章:

objective-c - 使用Obj-C,Xcode和libxml2的简单libxml2 XML解析示例?

ios - 删除前导逗号

ios - 错误: Expression resolves to an unused function (array with closure)

swift - 什么是占位符?为什么我们需要为泛型定义占位符数据类型?

ios - 在点击按钮时动画滚动到 tableview 的底部?

iOS-charts 带有负值的条形图

generics - Box inverse traits/Where boxes 子句

c# - 如何在 C# 中正确处理相关但不同类的调用方法

swift defer 语句不会断点但会打印

swift - handleOpenURL,第二个参数(sourceApplication)使用什么值?