I have a little example where the line
items.append(Item(value: "A", id: index))
fails with:
Type 'Item' has no member 'init'
and I don't understand the problem. Can you help?
struct Model<Item> where Item: Equatable {
var items = Array<Item>()
init(){
items.append(Item(value: "A", id: index))
}
}
struct Item: Identifiable, Equatable {
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.id == rhs.id
}
var value: any Equatable
var id: Int
}
CodePudding user response:
The error occurs because the generic type Item
has nothing to do with the struct Item
and the compiler treats Item
as generic type which doesn't have an initializer.
As you append the concrete type Item
in the init
method the generic type is pointless.
struct Model {
var items = Array<Item>()
init(){
items.append(Item(value: "A", id: 1))
}
}
which is practically the same as
struct Model {
var items = [Item(value: "A", id: 1)]
}
To clarify the issue this is a generic method with a different type name
struct Model<M : Equatable> {
var items = Array<M>()
init(){
items.append(Item(value: "A", id: 1))
}
}
Of course this throws the compiler error
Cannot convert value of type 'Item' to expected argument type 'M'
You can cast the type
items.append(Item(value: "A", id: 1) as! M)
but this makes the generic type pointless – as mentioned – because now M
is equal to static Item
and if you try to specify another type
let model = Model<String>()
you'll get a runtime error
Could not cast value of type '__lldb_expr_1.Item' (0x104dc0118) to 'Swift.String' (0x1f7c94ab8).
which causes a crash.