为什么 required 关键字 init 在通用 Array where 子句中是强制性的?
Why is required keyword init mandatory inside a generic Array where clause?
在此下标代码:
extension Array where Element: Foo {
subscript(key: String) -> Any? {
get {
return self.first(where: { [=10=].key == key })
}
set {
self.append(Element(key: key, value: newValue))
}
}
}
class Foo {
var key: String
var value: Any?
// Why "required"?
required init(key: String, value: Any?) {
self.key = key
self.value = value
}
}
为什么 required
必须在 Foo.init 前面?
如果删除它,我会收到此错误:
Constructing an object of class type 'Array<Element>.Element' (aka 'Element') with a metatype value must use a 'required' initializer
您需要标记初始值设定项 required
,因为您从适用于从 Foo
继承的所有类型(包括 Foo
本身)的通用扩展中使用它。但是,如果您没有将初始化器标记为 required
,您的 Foo
子 class 可能不会继承该初始化器,以防它们至少定义了一个指定的初始化器,如 [=21] 中所述=].
因此,除非您标记 Foo
required
的 init(key: String, value: Any?)
初始值设定项,否则您的通用 Array 扩展无法保证扩展中调用的初始值设定项方法对于扩展的所有类型都存在适用于。
如果您只想将扩展应用于 Foo
class 而不想将其应用于其子 class,您可以使用 extension Array where Element == Foo {...
在这种情况下,您不需要根据需要标记初始化器,因为 Foo
类型保证具有该初始化器。
The required
keyword means that inheriting classes must provide an implementation of the method.
而 extension Array where Element: Foo
意味着扩展应该适用于继承自 Foo
的所有 类,因此所有 required
都可以实现 init(key: String, value: Any?)
。
因此必须添加 required
关键字以确保这一点。
如果是 extension Array where Element == Foo
,则不需要 required
,因为类型 Foo
已定义 init
并具有正确的签名,因此无需有任何支票。
将 Foo
设为最终版本 (final class Foo {}
) 也将删除 required
中的需求。
在此下标代码:
extension Array where Element: Foo {
subscript(key: String) -> Any? {
get {
return self.first(where: { [=10=].key == key })
}
set {
self.append(Element(key: key, value: newValue))
}
}
}
class Foo {
var key: String
var value: Any?
// Why "required"?
required init(key: String, value: Any?) {
self.key = key
self.value = value
}
}
为什么 required
必须在 Foo.init 前面?
如果删除它,我会收到此错误:
Constructing an object of class type 'Array<Element>.Element' (aka 'Element') with a metatype value must use a 'required' initializer
您需要标记初始值设定项 required
,因为您从适用于从 Foo
继承的所有类型(包括 Foo
本身)的通用扩展中使用它。但是,如果您没有将初始化器标记为 required
,您的 Foo
子 class 可能不会继承该初始化器,以防它们至少定义了一个指定的初始化器,如 [=21] 中所述=].
因此,除非您标记 Foo
required
的 init(key: String, value: Any?)
初始值设定项,否则您的通用 Array 扩展无法保证扩展中调用的初始值设定项方法对于扩展的所有类型都存在适用于。
如果您只想将扩展应用于 Foo
class 而不想将其应用于其子 class,您可以使用 extension Array where Element == Foo {...
在这种情况下,您不需要根据需要标记初始化器,因为 Foo
类型保证具有该初始化器。
The
required
keyword means that inheriting classes must provide an implementation of the method.
而 extension Array where Element: Foo
意味着扩展应该适用于继承自 Foo
的所有 类,因此所有 required
都可以实现 init(key: String, value: Any?)
。
因此必须添加 required
关键字以确保这一点。
如果是 extension Array where Element == Foo
,则不需要 required
,因为类型 Foo
已定义 init
并具有正确的签名,因此无需有任何支票。
将 Foo
设为最终版本 (final class Foo {}
) 也将删除 required
中的需求。