V1ru8
V1ru8

Reputation: 6147

Calling function with generic protocol as return type

The following example should create concrete objects for abstract protocols.

class ClassA<T: FloatingPointType> {}

protocol ProtocolA
{
    typealias T: FloatingPointType
    var value : ClassA<T>? { get set }
}

class ClassImplProtocolA<T: FloatingPointType> : ProtocolA
{
    var value : ClassA<T>? {
        get {
            return nil
        }
        set {
        }
    }
}

class Factory
{
    class func createProtocol<PA: ProtocolA where PA.T: FloatingPointType>() -> PA
    {
        let concreteObject = ClassImplProtocolA<PA.T>()
        let abstractObject = concreteObject as? PA
        return abstractObject!
    }
}

Now two questions: Is it possible to avoid the as? PA? and how does the syntax look like to call Factory.createProtocol<...>()?

Or how do I work around this? All I want is an object of the abstract type PrtocolA<FloatingPointType> without exposing ClassImplProtocolA.

Upvotes: 0

Views: 88

Answers (1)

Qbyte
Qbyte

Reputation: 13263

First you cannot avoid as? PA since the return Type is determined by the type inference like this:

let prot: ClassImplProtocolA<Double> = Factory.createProtocol()
let prot = Factory.createProtocol() as ClassImplProtocolA<Double>

Another issue in this case is that you cannot use FloatingPointType as generic type (has Self requirements) and you have to use one which conforms to this protocol (like Double and Float).

In Swift's standard library they use AnySequence, AnyGenerator,... (generic structs) in order to have an abstract type of a protocol which has Self requirements. Unfortunately you cannot make a type AnyProtocolA<FloatingPointType> because the generic type itself has Self requirements.

Upvotes: 1

Related Questions