swift - 从泛型类重写初始值设定项

标签 swift generics initializer

open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
    public override init(_ data: T, getter: @escaping (T) -> U) {
        super.init(data, getter: getter)
    }
}

open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
    let data: T
    let getter: (T) -> U

    public init(_ data: T, getter: @escaping (T) -> U) {
        self.data = data
        self.getter = getter
    }
}

open class TableItem: NSObject {
    public var title: String?
}

奇怪的是,无法覆盖子类CheckItem中的init。

编译器提示初始化程序没有覆盖其父类(super class)中指定的初始化程序。它提示如果我删除 override 关键字,则覆盖声明需要“override”关键字。

这让我发疯,有人帮忙吗?提前致谢。

更奇怪的部分是它在 LabelItem 中工作

open class LabelItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: DataTableItem<T,U,V>{

public override init(_ data: T, getter: @escaping (T) -> U) {
    super.init(data, getter: getter)
}

完整代码可在此处获取 https://github.com/magerate/TableMaker

编辑

let checkItem = CheckItem<People, Bool>(people, getter: {(p: People) -> Bool in
        p.isGirl
    })

如果不尝试创建任何 CheckItem 实例,它就会编译。但提示

Cannot convert value of type 'People' to expected argument type 'Bool'

当尝试创建 CheckItem 的新实例时。

这里的类型推断似乎不正确。

编辑

当我将代码部署到 swift 框架时它可以工作。搞什么啊

最佳答案

我不确定您到底出了什么问题。当我运行你的代码时,一切似乎都很好。您确定正确实例化了实例吗?

let checkItem = CheckItem("Check item data") { (string: String) -> String in
    return string + "checkItem"
}


let labelItem = LabelItem<String, String, Int>("Label item") { (string: String) -> String in
    return string + "labelItem"
}


let dataTableItem = DataTableItem<String, String, Int>("Data table item") { (string: String) -> String in
    return string + "dataTableItem"
}

LabelItemDataTableItem你有一个通用的 V它不在任何地方使用,也不是参数,因此您需要在实例化时明确您的类型,因为您没有传递 V在 init 中输入类型,编译器无法推断类型。因此<String, String, Int>或任何其他满足约束的类型。

编辑:

查看你的项目代码后(该项目没有在我的 Xcode 上运行,我只将相关代码复制到我的项目中),我仍然没有发现问题 - CheckItem 的两个初始化程序编译:

open class TableItem: NSObject {
    public var title: String?
}

open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
    let data: T
    let getter: (T) -> U

    public weak var host: TableItemHost?

    public init(_ data: T, getter: @escaping (T) -> U) {
        self.data = data
        self.getter = getter
    }
}

public protocol TableItemHost: class {}

open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
    public init(_ data: T, host: TableItemHost, getter: @escaping (T) -> U) {
        super.init(data, getter: getter)
        self.host = host
    }

    public override init(_ data: T, getter: @escaping (T) -> U) {
        super.init(data, getter: getter)
    }
}

创建实例:

let checkItem1 = CheckItem("Check item 1 ") { (string: String) -> String in
    return string
}

class Host: TableItemHost {}
let host = Host()
let checkItem2 = CheckItem("Check item 2 ", host: host) { (string: String) -> String in
    return string
}

print(checkItem1.data)
print(checkItem2.data)

将我的代码复制粘贴到 Playground 中,然后亲自查看。也许除了初始化程序之外还有其他原因导致了错误。

对于测试,您还可以尝试注释掉 CheckItem 的两个初始值设定项并使用继承的初始值设定项实例化它。这应该有效,因为 CheckItem将不再有自己指定的初始值设定项 ( https://stackoverflow.com/a/31459131/1433612 )

关于swift - 从泛型类重写初始值设定项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50346340/

相关文章:

Swift:尝试获取坐标,但不知道如何调用 locationManager() 函数

java - 调用泛型类型类中的方法

java - Java 中的泛型阻止方法调用

java - 如何处理java中的类型有界通配符

java - 双括号初始值设定项和数组

string - Swift String init 不明确(此代码调用哪个 String.init 方法?)

ios - 从新的 Storyboard实例化 ViewController

swift - 仅在将对象添加到 CoreData 后无法在 bundle 中找到 NIB?

arrays - 从类数组列表中检查 "isKind(of: )"

c - 无效的初始化程序编译器错误在结构数组的malloc