Is there a way to have an array (or any generic type really) of generics with a type parameter conforming to a protocol?
protocol MyProtocol {}
struct MyStruct<T: MyProtocol> {
let myProp: T
}
// Generic parameter 'T' could not be inferred
// Explicitly specify the generic arguments to fix this issue
let array1 = [MyStruct]()
// Value of protocol type 'MyProtocol' cannot conform to 'MyProtocol';
// only struct/enum/class types can conform to protocols
let array2 = [MyStruct<MyProtocol>]()
// Type 'Any' does not conform to protocol 'MyProtocol'
let array3 = [MyStruct<Any>]()
protocol MyProtocol2 {
associatedtype T = MyProtocol
var myProp: T { get }
}
extension MyStruct: MyProtocol2 {}
// Protocol 'MyProtocol2' can only be used as a generic constraint because it has Self or
// associated type requirements
let array4 = [MyProtocol2]()
The array can have MyStruct
s with a different type parameter.
Ideally, this should work:
struct MyStruct2<T: MyProtocol> {
let myProp: T
let myFunc: (T) -> Void
}
let array = [MyStruct2</* something? */>]()
array.forEach { $0.myFunc($0.myProp) }
I have read Protocol can only be used as a generic constraint because it has Self or associatedType requirements, but that solution does not work in my situation as the items in the array are MyStruct
with any type that conforms to MyProtocol
.
I have also read Usage of protocols as array types and function parameters in swift and other similar questions, but the solutions also aren't appropriate.
array: [MyStruct<MyType>]
wherestruct MyType: MyProtocol {}
– Joakim DanielsonMyStruct<T: MyProtocol>
implies a real type T that adopts the protocol. So under the hood you would have a type MyStruct-where-T-is-A and another type MyStruct-where-T-is-B. Those are unrelated types. You cannot make an array of these things because they have nothing in common. This may be just another variant on stackoverflow.com/questions/33112559/… – mattMyStruct
really needs to be generic? If you want something likelet array2 = [MyStruct<MyProtocol>]()
, this probably means you don't want to use a generic inMyStruct
– rraphael