【问题标题】:Implementing a concrete type's property override of its protocol extension default in array of metatypes在元类型数组中实现具体类型的属性覆盖其协议扩展默认值
【发布时间】:2020-05-24 19:11:00
【问题描述】:

我创建了一个进程,它加载资源并使用我的程序中定义的类的某些元类型的类型属性。由于它们在实例化时是不同的类型,但在需要同时提供所有资源时是相似的,因此我使用符合SomeProtocol 协议的元类型数组来创建[SomeProtocol.Type] 类型的数组。当遍历数组并调用每个类型的someDefaultInt 属性(默认为1 的扩展SomeProtocol)时,即使自定义实现由符合协议的具体类给出,也会调用协议扩展的值(见下文)

注意:以下代码是用 Swift 5.2 编写的,因此每个类中的单表达式只读类型属性 someDefaultInt 可以省略 return 关键字

protocol SomeProtocol {
    static var myInt: Int { get set }
}

extension SomeProtocol {
    static var someDefaultInt: Int { 1 }
}

class ConcreteType: SomeProtocol {
    static var myInt: Int = 4
    static var someDefaultInt: Int { 2 } // Custom implementation
}

class ConcreteTypeII: SomeProtocol {
    static var myInt: Int = 5
    static var someDefaultInt: Int { 3 } // Custom implementation
}

var someTypes: [SomeProtocol.Type] = [ConcreteType.self, ConcreteTypeII.self]
someTypes.forEach { print($0.myInt) }
someTypes.forEach { print($0.someDefaultInt) }
/*
    Prints
    4
    5
    1
    1
*/

$0 转换为特定元类型确实会导致调用someDefaultInt 的正确自定义实现值。问题是:如果只知道它们符合协议,我如何确保为每个元类型调用自定义实现?是否有必要事先知道数组中使用的元类型,或者实现一个大的switch 语句,并将案例转换为特定的元类型?

【问题讨论】:

    标签: swift


    【解决方案1】:

    如果您希望它享受动态调度,请在协议定义中包含someDefaultInt

    protocol SomeProtocol {
        static var myInt: Int { get set }
        static var someDefaultInt: Int { get }
    }
    
    extension SomeProtocol {
        static var someDefaultInt: Int { 1 }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2018-07-25
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多