为什么 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 requiredinit(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 中的需求。