首页 文章

实例化存储在元类型字典中的类

提问于
浏览
1

我按照Make a Swift dictionary where the key is "Type"?的解决方案创建了可以使用类类型作为键的字典 . 我想要做的是:我有一个字典应该存储类类型(类型为metatype)作为键的类型:

class MyScenario {
    static var metatype:Metatype<MyScenario> {
        return Metatype(self)
    }
}


var scenarioClasses:[Metatype<MyScenario>: MyScenario.Type] = [:]

然后我有方法来注册和执行场景:

public func registerScenario(scenarioID:MyScenario.Type) {
    if (scenarioClasses[scenarioID.metatype] == nil) {
        scenarioClasses[scenarioID.metatype] = scenarioID
    }
}

public func executeScenario(scenarioID:MyScenario.Type) {
    if let scenarioClass = scenarioClasses[scenarioID.metatype] {
        let scenario = scenarioClass()
    }
}

......问题出在最后一行:

使用元类型值构造类类型为“MyScenario”的对象必须使用“必需”初始化程序 .

看起来编译器在这一点上很困惑,因为我不能在该任务中使用'required' . 有没有人知道如何在 executeScenario() 中实例化 scenarioClass

1 回答

  • 1

    这必须做好这项工作 .

    import Foundation
    
    struct Metatype<T> : Hashable
    {
        static func ==(lhs: Metatype, rhs: Metatype) -> Bool
        {
            return lhs.base == rhs.base
        }
    
        let base: T.Type
    
        init(_ base: T.Type)
        {
            self.base = base
        }
    
        var hashValue: Int
        {
            return ObjectIdentifier(base).hashValue
        }
    }
    
    public class MyScenario
    {
        var p: String
    
        public required init()
        {
            self.p = "any"
        }
    
        static var metatype:Metatype<MyScenario>
        {
            return Metatype(self)
        }
    }
    
    var scenarioClasses:[Metatype<MyScenario>: MyScenario.Type] = [:]
    
    public func registerScenario(scenarioID:MyScenario.Type)
    {
        if (scenarioClasses[scenarioID.metatype] == nil)
        {
            scenarioClasses[scenarioID.metatype] = scenarioID
        }
    }
    
    public func executeScenario(scenarioID:MyScenario.Type)
    {
        if let scenarioClass = scenarioClasses[scenarioID.metatype]
        {
            let scenario = scenarioClass.init()
            print("\(scenario.p)")
        }
    }
    
    // Register a new scenario
    registerScenario(scenarioID: MyScenario.self)
    
    // Execute
    executeScenario(scenarioID: MyScenario.self)
    
    // Should print "any"
    

相关问题