Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift type erasure protocol with required init method

I have the protocol that conform Equatable

protocol TestProtocol: Equatable {
    var id: Int {get}
}

func ==<T: TestProtocol>(lhs: T, rhs: T) -> Bool {
    return lhs.id == rhs.id
}

To have opportunities to store TestProtocol value we should use type erasure.

class AnyTestProtocol<T: TestProtocol>: TestProtocol {
    var id: Int {
        return item.id
    }

    private let item: T

    init(_ testProtocol: T) {
        self.item = testProtocol
    }
}

And, after all, we can use it, like this struct TestStruct: TestProtocol { let id: Int }

let a = TestStruct(id: 1)
let b = TestStruct(id: 1)

a == b /// true

// let a = TestStruct(id: 1)
// let b = TestStruct(id: 0)
// a == b /// false

And all ok. But I want to use TestProtocol with required init method, such as init(id: Int). How can I implement AnyTestProtocol If TestProtocol contains required init method?

protocol TestProtocol: Equatable {
    var id: Int {get}

    /// Required init method for every protocol implementation
    init(id: Int)
}

func ==<T: TestProtocol>(lhs: T, rhs: T) -> Bool {
    return lhs.id == rhs.id
}

class AnyTestProtocol<T: TestProtocol>: TestProtocol {
    var id: Int {
        return item.id
    }

    private let item: T

    required init(id: Int) {
        ????????
    }

    init(_ testProtocol: T) {
        self.item = testProtocol
    }
}
like image 610
Vladislav Avatar asked May 14 '26 01:05

Vladislav


1 Answers

Just forward the required init(id:) call to T:

class AnyTestProtocol<T: TestProtocol>: TestProtocol {

    // ...

    required init(id: Int) {
        self.item = T(id: id)
    }

    // ...
}
like image 102
Martin R Avatar answered May 15 '26 15:05

Martin R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!