In Swift I can do the following:
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)
currentType
is a Metatype
: this means I could pass another struct name (eg. Person, etc.) and instanceFromType
would contain a struct of another type.
But, suppose I want to pass currentType
as a function argument and then, inside the body of the function, create instanceFromType
: how would I do?
I tried this one:
func f(m:Any.Type){
let instanceFromType = m.init(name: "Jessie", age: 54)
print(instanceFromType)
}
f(m:currentType)
but I get:
'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type
What am I doing wrong? Any help is appreciated.
[UPDATE]
I forgot to mention that I found this one is working, but I really can't understand why:
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)
You cannot call m.init(name: "Jessie", age: 54)
for an arbitrary
type m
, because the type does not necessarily have such an
initializer.
What you can do is to define a protocol for a type which can
be initialized from those arguments, and restrict the argument
of f
accordingly:
protocol InitializableFromNameAndAge {
init(name: String, age: Int)
}
func f(type: InitializableFromNameAndAge.Type) {
let instance = type.init(name: "Jessie", age: 34)
print(instance)
}
Then declare protocol conformance for your types
struct Employee: InitializableFromNameAndAge {
var name:String
var age:Int
}
and then
let currentType = Employee.self
f(type: currentType)
works as expected.