2017-09-15 4 views
0

Je suis en train de créer un simple struct d'effacement de type à Swift 4:« erreur de segmentation: 11 » dans la classe générique

protocol DataProvider 
{ 
    associatedtype ItemType 

    subscript(index: Int) -> ItemType { get } 
} 

struct AnyDataProvider<providerType: DataProvider> : DataProvider 
{ 
    private var _subscript: (_ index: Int) -> providerType.ItemType 

    init<P : DataProvider>(_ base: P) where P.ItemType == providerType.ItemType 
    { 
    _subscript = base.subscript 
    } 

    subscript(index: Int) -> providerType.ItemType 
    { 
    return _subscript(index) 
    } 
} 

mais je reçois une erreur de segmentation: 11 sur la ligne qui déclare la initialiseur .

Des idées, en dehors de signaler comme un bug?

+0

C'est le type-effacé pas. Votre 'AnyDataProvider' est paramétré par un' DataProvider'. Tout ce que vous faites est d'essayer de rendre possible le traitement d'un DataProvider comme s'il s'agissait d'un DataProvider différent (sans bénéfice évident, puisque les types sont identiques). Si vous voulez vraiment effacer le 'DataProvider', alors votre' AnyDataProvider' devrait être paramétré par le 'ItemType' lui-même, pas par un' DataProvider'. –

Répondre

0

Yesss! Le problème est que vous ne pouvez pas affecter une "méthode" d'indice à une référence de fermeture. Pour ce faire, Slava Pestov d'Apple m'a montré l'astuce de l'attribution d'une fermeture anonyme, qui appelle l'indice.

Voici le code fini:

protocol DataProvider 
{ 
    associatedtype ItemType 

    subscript(index: Int) -> ItemType { get } 
} 

struct AnyDataProvider<itemType> : DataProvider 
{ 
    private let _subscript: (Int) -> itemType 

    subscript(index: Int) -> itemType 
    { 
    return _subscript(index) 
    } 

    init<providerType : DataProvider>(_ base: providerType) where providerType.ItemType == itemType 
    { 
    _subscript = { base[$0] } 
    } 
}