4bottiglie
4bottiglie

Reputation: 540

Array with associatedtype protocol

I'am coming from java and I have little difficulties to learn the patterns.

I have the first protocol

protocol Interval
{

}

And the second:

protocol Event
{
    associatedtype IntervalType: Interval

    var interval: IntervalType

    func doSomething(param: IntervalType )
}

How can i make an array with the type Event?

I took a look at the type-erase and the solution that it gives it to create a struct like this one:

public struct AnyEvent<intervalType: Interval>: Event {...}

But it only gives me the possibility to create an array with any event type and only one type of Interval, I want to make an array with any kind of Events that could contain any kind of Intervals, something like: [AnyEvent] or [AnyEvent<Interval>]

I also want to ask if there is a possibility to make Event extend Equatable and define it in the type-erase.

Edit:

Hoping someone is good at both swift and java, and can provide a translated pattern for this:

A simple common interval interface:

interface ReadableInterval {...}

Two types that confirms the readable interval:

class Interval implements ReadableInterval {...}

class MutableInterval implements: ReadableInterval {...}

A common events interface:

interface ReadablEvent
{
   ReadableInterval getInterval();
}

Two types of events that could have different intervals, with the specialized return type of the methods:

class Event implements: ReadablEvent
{

   private Interval interval = new Interval();

   Interval getInterval()
   {
       return interval;
   }
}

class MutableEvent implements: ReadablEvent
{

   private MutableInterval interval = new MutableInterval();

   MutableInterval getInterval()
   {
       return interval;
   }
}

and then i want to have a list or array with the both Event and MutableEvent like:

ArrayList<ReadableEvent>

or

ReadableEvent[]

Upvotes: 1

Views: 319

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59496

As you know in Swift you cannot declare an array of a protocols with an associated type (please read this for more details)

However you can declare a new protocol like this

protocol AnyEvent {
    var interval: Interval { get }
    func doSomething(param: Interval )
}

Your 3 protocols should now look like this

protocol Interval {

}

protocol AnyEvent {
    var interval: Interval { get }
    func doSomething(param: Interval )
}

protocol Event: AnyEvent {
    associatedtype IntervalType: Interval
    var interval: IntervalType { get }
    func doSomething(param: IntervalType )
}

Usage

To use these protocols we need some structs (or classes) that conform to them

struct TimeInterval: Interval { }
struct TapEvent: AnyEvent {
    var interval: Interval = TimeInterval()
    func doSomething(param: Interval) {
        print("It's a tap")
    }
}
struct GestureEvent: AnyEvent {
    var interval: Interval = TimeInterval()
    func doSomething(param: Interval) {
        print("It's a gesture")
    }
}

Now we can

var events = [AnyEvent]()
events.append(TapEvent())
events.append(GestureEvent())
for event in events {
    event.doSomething(TimeInterval())
}

It's a tap

It's a gesture

I also want to ask if there is a possibility to make Event extend Equatable and define it in the type-erase

Yes you just need to add the declaration

protocol Event: AnyEvent, Equatable {
    associatedtype IntervalType: Interval
    var interval: IntervalType { get }
    func doSomething(param: IntervalType )
}

Now you are forcing every struct o class conform to Event to be Equatable.

Upvotes: 1

Related Questions