I tried to make array or var of ProtocolA
but I ran into some errors.
What is going on here?
protocol ProtocolA {
associatedtype ProtocolAType
var prop1: ProtocolAType { get set }
func description()
func methodA(param1: ProtocolAType) -> ProtocolAType
}
extension ProtocolA {
func description() {
print(self)
}
func methodA(param1: ProtocolAType) -> ProtocolAType {
param1
}
}
struct StructA: ProtocolA {
var prop1: Int
}
struct StructB: ProtocolA {
var prop1: String
}
var item1: some ProtocolA = StructA(prop1: 1)
var item2: some ProtocolA = StructB(prop1: "1")
item1.description()
//Cannot invoke 'methodA' with an argument list of type '(param1: Int)'
var result1 = item1.methodA(param1: 1)
//Cannot invoke 'methodA' with an argument list of type '(param1: String)'
var result2 = item1.methodA(param1: "1")
//Cannot convert value of type '[Any]' to specified type 'some ProtocolA'
//Property declares an opaque return type, but cannot infer the underlying type from its initializer expression
var items1: some ProtocolA = [StructA(prop1: 1), StructB(prop1: "1")]
//Property declares an opaque return type, but cannot infer the underlying type from its initializer expression
//Return type of var 'items2' requires that '[StructA]' conform to 'ProtocolA'
var items2: some ProtocolA = [StructA(prop1: 1), StructA(prop1: 1)]
for item in items2 {
item.method(2)
}
I created CustomCollection
but it can't work with associatedtype
struct CustomCollection<T> {
typealias Items = [T]
private var items: Items
init(items: Items) {
self.items = items
}
}
extension CustomCollection: ExpressibleByArrayLiteral {
init(arrayLiteral elements: T...) {
self.items = elements
}
}
extension CustomCollection: Collection {
typealias Index = Items.Index
typealias Element = Items.Element
var startIndex: Index { items.startIndex }
var endIndex: Index { items.endIndex }
subscript(index: Index) -> Iterator.Element {
get { items[index] }
set { items[index] = newValue }
}
func index(after i: Index) -> Index {
items.index(after: i)
}
}
I mist how to specify the associatedtype
//Protocol 'ProtocolA' can only be used as a generic constraint because it has Self or associated type requirements
var items4: CustomCollection<ProtocolA> = [StructA(prop1: 1), StructB(prop1: "1")]
//An 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class
var items5: some CustomCollection<ProtocolA> = [StructA(prop1: 1), StructB(prop1: "1")]