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:
- Use a concrete type directly, i.e.
let router: MyStartViewClass
with this conformance declaration, elsewhere:class MyStartViewClass: StartRouterProtocol { ... }
) - 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
Get Applicationdidfinishlaunching Call in a View Controller. Parse Not Initialized Yet
How to Get Access Token from Instagram API
Cannot Get Newpassword to Generate Strong Password and Autofill
iOS 10 App Crashes When Accessing Camera
Using Index from Foreach in Other Array
How to Use Publishers.Combinelatest to Get 1 Publisher
How to Get Textfields from Static Cells in UItableviewcontroller? Swift
Emitting a Warning for a Deprecated Swift Protocol Method in Implementing Types
Location Access Request in iOS 11
Is There a Method to Check The UIcollectionview Item Drag Cancellation If The Item Wasn't Moved
Table View's 'Cellforrow(At:)' Is 'Nil' in Unit Test
Convert Time String into Date Swift
Xcode Failed to Resolve Dependency Firebase - Googleappmeasurement Does Not Match Requirement
How to Initialize UIbezierpath to Draw a Circle in Swift