Swift generic completion handler -
i'm trying figure out how create generic completion handler. below example illustrating example "internal" generic completion handler , same generic completion handler want able create if in "external" form. problem don't know how write equivalent of internalcompletion<t: myenum>...
in completion handler. i've written in externalcompletion
function i'd imagine like: along lines of func externalcompletion(_ completer<t: myenum>: ((t) -> void) t: hashable))
, not correct. i'm trying possible? hunch swift won't let completion handler remain generic, requiring type casting @ function level, defeat purpose per example (i.e. func externalcompletetion<t: myenum>(_ completer: ((t) -> void)) t: hashable
, problem being have choose between enuma, enumb, , enumc, not being able run completer on three.)
typealias myenumkeyeddata<t: myenum> = [t: string] t: hashable // mark : - myenum protocol protocol myenum { static func all<t: myenum>(_:t.type) -> [t] t: hashable static var all: [myenum] { } } extension myenum { static func all<t: myenum>(_:t.type) -> [t] t: hashable { return self.all as! [t] } } // mark : - enums enum enuma: myenum { case first static var all: [myenum] { return [enuma.first]} } enum enumb: myenum { case first static var all: [myenum] { return [enumb.first]} } enum enumc: myenum { case first static var all: [myenum] { return [enumc.first]} } // mark : - myenum data iterator class mydataenumiterator { var dataa: myenumkeyeddata<enuma> = [:] var datab: myenumkeyeddata<enumb> = [:] var datac: myenumkeyeddata<enumc> = [:] func updatedata<t: myenum>(_ key: t, _ value: string) t: hashable { switch t.self { case enuma.type: dataa[key as! enuma] = value case enumb.type: datab[key as! enumb] = value case enumc.type: datac[key as! enumc] = value default: fatalerror("enum not exist") } } // internal (this works) func internalenumiterator() { key in enuma.all(enuma.self) { internalcompletion(key) } key in enumb.all(enumb.self) { internalcompletion(key) } key in enumc.all(enumc.self) { internalcompletion(key) } } func internalcompletion<t: myenum>(_ key: t) t: hashable { let value = "\(key)" updatedata(key, value) } // external (this doesn't, sketching idea) func externalenumiterator(_ completer<t: myenum>: ((t) -> void) t: hashable) { key in enuma.all(enuma.self) { completer(key) } key in enumb.all(enumb.self) { completer(key) } key in enumc.all(enumc.self) { completer(key) } } } // mark : - test cases (internal works, external not, sketching example) let iterator = mydataenumiterator() iterator.externalenumiterator({ <t: myenum> (t) t: hashable in let value = "\(key)" iterator.updatedata(key, value) }) iterator.internalenumiterator()
here working version of code minimal changes necessary going
typealias myenumkeyeddata<t: myenum> = [t: string] t: hashable // mark : - myenum protocol protocol myenum { static func all<t: myenum>(_:t.type) -> [t] t: hashable static var all: [myenum] { } } extension myenum { static func all<t: myenum>(_:t.type) -> [t] t: hashable { return self.all as! [t] } } // mark : - enums enum enuma: myenum { case first static var all: [myenum] { return [enuma.first]} } enum enumb: myenum { case first static var all: [myenum] { return [enumb.first]} } enum enumc: myenum { case first static var all: [myenum] { return [enumc.first]} } // mark : - myenum data iterator class mydataenumiterator { var dataa: myenumkeyeddata<enuma> = [:] var datab: myenumkeyeddata<enumb> = [:] var datac: myenumkeyeddata<enumc> = [:] func updatedata(_ key: myenum, _ value: string) { switch key { case let key enuma: dataa[key] = value case let key enumb: datab[key] = value case let key enumc: datac[key] = value default: fatalerror("enum not exist") } } // internal (this works) func internalenumiterator() { key in enuma.all(enuma.self) { internalcompletion(key) } key in enumb.all(enumb.self) { internalcompletion(key) } key in enumc.all(enumc.self) { internalcompletion(key) } } func internalcompletion<t: myenum>(_ key: t) t: hashable { let value = "\(key)" updatedata(key, value) } func enumiterator(_ compeltitionhandler: (myenum) -> void) { key in enuma.all(enuma.self) { compeltitionhandler(key myenum) } key in enumb.all(enumb.self) { compeltitionhandler(key myenum) } key in enumc.all(enumc.self) { compeltitionhandler(key myenum) } } } let iterator = mydataenumiterator() iterator.enumiterator{ key in let value = "\(key)" iterator.updatedata(key, value) } iterator.internalenumiterator()
here sane version of code removes nonsense, , adds subscript syntax:
// mark : - myenum protocol protocol myenum { static func all() -> [myenum] } // mark : - enums enum enuma: myenum { case first static func all() -> [myenum] { return [enuma.first] } } enum enumb: myenum { case first static func all() -> [myenum] { return [enumb.first] } } enum enumc: myenum { case first static func all() -> [myenum] { return [enumc.first] } } // mark : - myenum data iterator class mydataenumiterator { var dataa = [enuma: string]() var datab = [enumb: string]() var datac = [enumc: string]() subscript(key: myenum) -> string? { { switch key { case let key enuma: return dataa[key] case let key enumb: return datab[key] case let key enumc: return datac[key] default: fatalerror("enum not exist") } } set { switch key { case let key enuma: dataa[key] = newvalue case let key enumb: datab[key] = newvalue case let key enumc: datac[key] = newvalue default: fatalerror("enum not exist") } } } func enumiterator(_ body: (myenum) -> void) { enuma.all().foreach(body); enumb.all().foreach(body); enumc.all().foreach(body); } } let iterator = mydataenumiterator() iterator.enumiterator{ iterator[$0] = "\($0)" }
Comments
Post a Comment