Building Generic with varying types

Here's my sample code. I'm trying to create a function builder that generates ContainerType 's with some unrelated-type input. In the sample code, I'm using a boolean (my actual code is parsing raw data).

protocol ProtocolType {
	
}

struct ConformingA: ProtocolType {
	
}

struct ConformingB: ProtocolType {
	
}

struct ContainerType<E> where E: ProtocolType {
	let contents: E
	
	init(contents: E) {
		self.contents = contents
	}
}

func make(from bool: Bool) -> ContainerType<???> {
	if bool {
		return ContainerType(contents: ConformingA())
	} else {
		return ContainerType(contents: ConformingB())
	}
}

Where I've put the ??? is the point where it stops working. If I write any ProtocolType (which is my interpretation of what I need) I get the following error:

Type 'any ProtocolType' cannot conform to 'ProtocolType'

1 Like

To return different specialized types of ContainerType you have to type erase the containers:

protocol ContainerProtocol {
  associatedtype E: ProtocolType
  var contents: E { get } 
}

struct ContainerType<E>: ContainerProtocol where E: ProtocolType {
	let contents: E
	
	init(contents: E) {
		self.contents = contents
	}
}

func make(from bool: Bool) -> any ContainerProtocol {
	if bool {
		return ContainerType(contents: ConformingA())
	} else {
		return ContainerType(contents: ConformingB())
	}
}
1 Like

Aha, that's what I was missing - I understood I needed to somehow erase the generic type but it never occurred to me to do that with another protocol.