Home > OS >  Type 'Item' has no member 'init'
Type 'Item' has no member 'init'

Time:11-14

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.

  • Related