将Metatype作为函数参数

时间:2017-07-28 09:29:40

标签: swift struct metatype

在Swift中,我可以执行以下操作:

struct Employee{
    var name:String
    var age:Int
}

// Metatype
let currentType = Employee.self
// concrete instance
let instanceFromType = currentType.init(name: "Jessie", age: 54)

print(instanceFromType) // prints Employee(name: "Jessie", age: 54)

currentTypeMetatype:这意味着我可以传递另一个结构名称(例如Person等),instanceFromType将包含另一种类型的结构。

但是,假设我想将currentType作为函数参数传递,然后在函数体内创建instanceFromType:我该怎么做?

我试过这个:

func f(m:Any.Type){

  let instanceFromType = m.init(name: "Jessie", age: 54)
  print(instanceFromType)
}

f(m:currentType)

但我明白了:

  

'init'是该类型的成员;使用'type(of:...)'来初始化相同动态类型的新对象

我做错了什么?任何帮助表示赞赏。

[更新]

我忘了提到我发现这个工作正常,但我真的不明白为什么:

protocol Proto {
    init(name:String,age:Int)
}

struct Employee:Proto{
    var name:String
    var age:Int
    init(name:String,age:Int){
        self.name = name
        self.age = age
    }
}

let currentType = Employee.self

func f(m:Proto.Type){

    let instanceFromType = m.init(name: "Jessie", age: 54)
    print(instanceFromType)

}

f(m:currentType)

1 个答案:

答案 0 :(得分:2)

您无法为{em>任意致电m.init(name: "Jessie", age: 54) 键入m,因为类型不一定有这样的 初始化程序。

您可以做的是为可以的类型定义协议 从这些参数初始化,并限制参数 因此f

protocol InitializableFromNameAndAge {
    init(name: String, age: Int)
}

func f(type: InitializableFromNameAndAge.Type) {
    let instance = type.init(name: "Jessie", age: 34)
    print(instance)
}

然后声明您的类型的协议一致性

struct Employee: InitializableFromNameAndAge {
    var name:String
    var age:Int
}

然后

let currentType = Employee.self
f(type: currentType)

按预期工作。