0

Is it possible to declare a variable with the type of a generic protocol in Swift?

If no, what are the alternatives? It seems like a huge disadvantage that I cannot reuse a protocol with different type parameters, let alone mock it out.

Felix
  • 8,385
  • 10
  • 40
  • 59
  • 1
    You mean protocol with associated type? – user28434'mstep Oct 17 '16 at 11:54
  • Yes, I want to achieve what generic interfaces achieve in so many other languages. So far my workaround is to create a base class with no real functionality and overwrite it in subclasses. – Felix Oct 17 '16 at 12:14
  • Ok, it's not possible to declare variable of protocol with associated type in Swift 1-3. But it looks like Generics will be improved in Swift 4. Check https://github.com/apple/swift-evolution. – user28434'mstep Oct 17 '16 at 12:21
  • 2
    I'll wait until late 2017 then ;-) – Felix Oct 17 '16 at 12:37
  • You're most likely looking for a [type erasure](http://robnapier.net/erasure) – see for example [How do I add different types conforming to a protocol with an associated type to a collection?](http://stackoverflow.com/questions/31762045/how-do-i-add-different-types-conforming-to-a-protocol-with-an-associated-type-to) – Hamish Oct 17 '16 at 13:13
  • Another solution I found so far is to wrap instances in generic structs, i.e. `MyContainer` and then forward the constraints to the associated type of the contained instance. In this way, I don't need a "useless" base class with empty or error stub implementations, however, this adds programming overhead because all method calls need to be forwarded to the contained protocol instance. – Felix Oct 20 '16 at 08:24

2 Answers2

0

Im not sure if this is what you mean, but you can do:

public typealias SuccessBlock<T> = (_ data: T) -> (Void)

and then define variables:

var myBlock: SuccessBlock<String>

Tendai Moffatt
  • 236
  • 2
  • 4
0

My workaround is non-generic protocol. Agree about strange limitation thats hurts. Limitation due to missing associatedtype is must use base of element in protocol, all other internal can be used with generic type

//: Playground - noun: a place where people can play

import UIKit
import Foundation

class Item: NSObject {

}

protocol Datasource {

    subscript(index: Int) -> NSObjectProtocol? { get }
}

class BaseDatasource<Element: NSObjectProtocol>: Datasource {

    private(set) var data: [Element]?

    subscript(index: Int) -> NSObjectProtocol? {
        get {
            return data?[index]
        }
    }

    func sortedData(_ data: [Element]) -> [Element] {
        return data
    }
}

class ItemsDatasource: BaseDatasource<Item> {
    ///some specific code
}

var dataOfInts: Datasource?

dataOfInts = ItemsDatasource()//or BaseDatasource<Item>()
Mike Glukhov
  • 1,758
  • 19
  • 18