Reputation: 2519
I'm writing an async dictionary that returns a Future with the value:
The dictionary inside my class is generic, so the class is as well. Currently the user has to read the docs and know to set the dataCall
function, which is how the dictionary knows how to get a value for a key, in the form
var dataCall: ((key: Key) -> Future<Value, MyError>)?
But this requires other programmers to know about the data call and set it. So I wrote a protocol
protocol CacheDelegate {
typealias T: Hashable
typealias U
func dataCallForCacheManager(cacheManager: CacheManager<T, U>) → (key: T) → Future<Value, MyError>
}
However, then if I try and call this in init()
as
delegate.dataCallForCacheManager(self)
I get the error
Cannot invoke
dataCallForDictionary
with an argument list of type '(CacheManager)'
I also cannot make a var delegate: CacheDelegate?
because
Protocol
CacheDelegate
can only be used as a generic constraint because it has Self or associated type requirements.
So I find myself in a pickle where I can't pass myself as an argument, and I can't set a delegate to get my data call from this protocol. Am I missing something? I'm willing to do Swift 2 Voodoo.
The contents of a toy example (without Futures and the dictionary and everything) is below:
import Foundation
protocol Delegate {
typealias T: Hashable
typealias U
func dataCallForDictionary(dictionary: MyDictionary<T, U>) -> (T) -> (U)
}
struct MyDictionary<Key: Hashable, Value> {
typealias T = Key
typealias U = Value
init<Object: Delegate>(delegate: Object) {
dataCall = delegate.dataCallForDictionary(self)
// self.delegate = delegate
}
var delegate: Delegate?
var dataCall: ((key: Key) -> Value)?
}
Upvotes: 1
Views: 1118
Reputation: 22939
Taking your example, have you considered doing:
protocol Delegate {
func dataCallForDictionary<T: Hashable, U>(dictionary: MyDictionary<T, U>) -> T -> U
}
struct MyDictionary<Key: Hashable, Value> {
var delegate: Delegate?
var dataCall: ((key: Key) -> Value)?
init(delegate: Delegate) {
self.delegate = delegate
dataCall = delegate.dataCallForDictionary(self)
}
}
Upvotes: 1