Reputation: 189
I'm trying to create a simple type erasure struct in Swift 4:
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)
}
}
But I am getting a segmentation fault : 11 on the line that declares the initialiser.
Any ideas, apart from reporting it as a bug?
Upvotes: 0
Views: 150
Reputation: 189
Yesss!
The problem is that you cannot assign a subscript "method" to a closure reference.
To achieve this, Slava Pestov from Apple showed me the trick of assigning an anonymous closure, which calls the subscript.
Here is the finished code :
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] }
}
}
Upvotes: 1