swift 协议扩展默认实现与类中的实际实现

Hix*_*eld 5 swift swift-protocols

考虑以下代码:

protocol MyProtocol {
    static var name: String { get }
}

extension MyProtocol {
    static var name: String {
        return "unnamed"
    }
}

// does not specify its own name
class MyClass: MyProtocol {

}

//specifies its own name!
class MyClass2: MyProtocol {
    static var name: String {
        return "Specific name"
    }
}

let myClass = MyClass()
print("\(MyClass.name)")
//>>"unnamed"

let myClass2 = MyClass2()
print("\(MyClass2.name)")
//>>"Specific name"
Run Code Online (Sandbox Code Playgroud)

swift 是否保证对于具有协议属性(在本例中为“name”)的实际实现的类(例如在本例中为 MyClass2),这是从类中使用的,而不是默认的“name”实现之一通过协议扩展?

Dáv*_*tor 7

拥有所需协议函数/属性的默认实现意味着您的一致性类型不必实现该函数/属性,它们可以使用默认实现。

但是,如果符合类型确实实现了该函数/属性,则编译器将始终调用更具体的实现,即符合类中的实现,而不是默认的实现。

因此,即使您将 的实例存储MyClass2在类型 的变量中MyProtocol,您仍然可以MyClass2在访问该变量的属性时获得实现。

let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
Run Code Online (Sandbox Code Playgroud)

对于协议扩展中声明和定义的非必需属性/函数,行为有所不同。如果您仅在协议扩展中声明属性/函数,那么即使您在一致的类中为其提供了不同的实现,您也无法从类型为协议类型而不是协议类型的变量访问该实现。特定的符合类型。

protocol MyProtocol {
    static var name: String { get }
}

extension MyProtocol {
    static var name: String {
        return "unnamed"
    }

    // Optional protocol requirement
    static var nonRequired: String {
        return "nonRequired"
    }
}

// does not specify its own name
class MyClass: MyProtocol { }

//specifies its own name!
class MyClass2: MyProtocol {
    static var name: String {
        return "Specific name"
    }

    // Specific implementation
    static var nonRequired: String {
        return "Specific"
    }
}

let myClass = MyClass()
MyClass.name

let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
type(of: myClass2).nonRequired // "nonRequired"
MyClass2.nonRequired // "Specific"
Run Code Online (Sandbox Code Playgroud)