Implement Protocol with Different Associated Type

implement protocol with different associated type

I just fund a way to archive this. The trick is to add another associated type in one of the subtypes of the protocol:

protocol ConvertableInt : Convertable {
associatedtype TResI
typealias TargetType = TResI
}

extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(self.data) }
}

extension MyData : ConvertableInt {
typealias TResI = Int
func convert() -> TResI { return self.data }
}

This also allows to get rid of the second subtype for string.

While this passes the compiler it totally crashes at runtime!

The compiler always calls the method defined which was defined at the explicit typealias. In this case:

typealias TargetType = String

Which will result in interpreting the address as a integer and give you totally wrong results. If you define it vice versa it will simply crash because it tries to interpret the integer as a address.

returning swift protocol associated type in multiple methods

The solution you came up with by playing around is exactly what you need

As mentioned elsewhere, the main issue with your first protocol is that you're enforcing createSomeView() createAnotherView() both return the same type. While ViewA() and ViewB() are both candidates for V, since they conform to View they are still different types, and therefore cannot BOTH be V in a given object.

By defining both V1 and V2, you allow for each function to return a different type, or the same type, it's all acceptable. By making both V1 and V2 require View conformance, you allow for the some View syntax

Protocol restriction on another protocol associated type

As far as I can see MyStruct? (aka Optional) and Codable? (aka
Optional<Decodable & Encodable>) are equivalent?

No, they are not. MyStruct conforms to Codable but is not equivalent of it.

As in: every MyStruct is Codable but not every Codable is MyStruct.


You can try changing MyType == Codable? to MyType: Codable:

protocol MyProtocolCodable where Self: MyProtocol, MyType: Codable {}

as MyStruct is not equal to Codable?.

Get self of protocol with associated type

It is no different than when not using an associated type.

(any ViewCreator).self
String(describing: (any ViewCreator).self) // "ViewCreator"

In the future, you may have the option to use primary associated types to provide restrictions. But for now, this will compile and execute, but be considered <<< invalid type >>>.

protocol ViewCreator<ResultView> {
(any ViewCreator<EmptyView>).self

Swift: Set protocol's associated type in argument / member variable

ConsumerA needs to be generic. Replace ModuleName with your actual module name.

class ConsumerA<KeyValueStore: ModuleName.KeyValueStore>
where KeyValueStore.Key == String, KeyValueStore.Value == Int {

Also, your method pair should be a subscript instead.

subscript(key: Key) -> Value { get set }
keyValueStore["Hello"] = 5

Protocol inheritance with associated type

Once a protocol has an associated type, that protocol can't be used as a type by itself for instance declarations-- only for generic constraints and declaring conformance.

So in this case, Swift is saying "yeah, but what is the concrete type for StartRouterProtocol's associated type?"

In this case, it's asking you to either:

  1. Use a concrete type directly, i.e. let router: MyStartViewClass with this conformance declaration, elsewhere: class MyStartViewClass: StartRouterProtocol { ... })
  2. OR, push the need for a concrete type up one layer, as a generic constraint i.e.
class MyRouterController<T: StartRouterProtocol> {
let router: T
}

This is probably not what you were hoping for, but unfortunately associated types add complexity to how you use protocols, especially if you're familiar with generics & interfaces from other languages. (i.e. Java/C# interfaces)

You can work around some aspects of associated types by using a concept called "type erasure" -- but that can cause other problems and complexity.

Here's some further reading that may help: https://medium.com/monstar-lab-bangladesh-engineering/swift-from-protocol-to-associatedtype-then-type-erasure-a4093f6a2d08

protocol with same associated type name

Another workaround is to create a third, combined protocol:

protocol ReadWrite {
associatedtype R
associatedtype W
func read() -> R
func write(a: W)
}

It's not pretty, since it forces you to redeclare the protocol members, but it does keep it generic (you're not limited to String and Int).



Related Topics



Leave a reply



Submit