gpt4 book ai didi

swift - Swift 中的泛型约束和初始化器继承

转载 作者:行者123 更新时间:2023-11-30 12:56:32 24 4
gpt4 key购买 nike

我试图在既符合 A 又是 C 子类的类型上调用协议(protocol) A 所需的初始化程序。

如果C是基类,一切都很好。但是一旦 C 子类化另一个类(例如 B),它就会崩溃。

这就是我要说的:

protocol A {
init(foo: String)
}

class B {
init() {}
}

class C: B {}

func makeSomething<T: A>() -> T where T: B {
return T(foo: "Hi")
}

这有效。但是,如果我将 where T: B 更改为 where T: C,则会收到以下错误:传递给不带参数的调用的参数。它只允许我调用 Bs init

为什么我不能调用这个初始化器?我知道父类(super class)有自己指定的必须调用的初始值设定项。但是,当有人实际编写了 B 的子类并符合 A 的类时,就会强制执行这一点。 (例如,实现 init(Foo: String) 并在内部调用 super.init(bar: Int))。

如果有任何帮助,我们将不胜感激。谢谢!

最佳答案

如果基类已初始化所有属性,则 Swift 会为您的基类提供默认初始化程序,但在泛型情况下则不然,因为 Swift 可能会认为其属性尚未初始化。

因此,当您将返回类型限制为

func makeSomething<T: A>() -> T where T: C

它需要对 C 类进行初始化,因为 Swift 无法提供默认的初始化程序。但是如果删除 where 子句,一切都会正常工作

func makeSomething<T: A>() -> T {
return T(foo:"string")
}

如果你想返回return T(foo: "Hi"):

您收到错误,因为类 C 没有接受 init(foo: String)

的初始值设定项

将你的 C 类更改为

class C: A {
required init(foo: String) {

}
}

它至少提供一个接受参数类型的初始值设定项。

所以,请记住,如果您没有子类化,那么已经有一个初始化程序在完成您的工作,并且您不会收到错误。

关于swift - Swift 中的泛型约束和初始化器继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40334701/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com