汎用補完ハンドラの作成方法を理解しようとしています。下の例は、 "内部"の汎用補完ハンドラと、同じ汎用の補完ハンドラを示しています。私が "外部"フォームでそれを行うことができるのであれば、それを作成できます。問題は、私が完了ハンドラにinternalCompletion<T: MyEnum>...
の相当物を書く方法を知らないことです。私はexternalCompletion
の機能を書いています。それは、func externalCompletion(_ completer<T: MyEnum>: ((T) -> Void) where T: Hashable))
の行に沿ったものですが、明らかに正しくありません。私がしようとしていることは可能ですか?私の見方は、完了ハンドラが一般的なままではいけないということです。機能レベルでは常に型のキャストが必要です。つまり、私の例では目的を破ってしまいます(つまり、func externalCompletetion<T: MyEnum>(_ completer: ((T) -> Void)) where T: Hashable
、これはEnumA、 EnumB、およびEnumC、すべての3つでコンプリータを実行することができない。)Swift汎用補完ハンドラ
typealias MyEnumKeyedData<T: MyEnum> = [T: String] where T: Hashable
// MARK : - MyEnum Protocol
protocol MyEnum {
static func all<T: MyEnum>(_:T.Type) -> [T] where T: Hashable
static var all: [MyEnum] { get }
}
extension MyEnum {
static func all<T: MyEnum>(_:T.Type) -> [T] where T: Hashable { return Self.all as! [T] }
}
// MARK : - My 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) where T: Hashable {
switch T.self {
case is EnumA.Type: dataA[key as! EnumA] = value
case is EnumB.Type: dataB[key as! EnumB] = value
case is EnumC.Type: dataC[key as! EnumC] = value
default: fatalError("Enum does not exist")
}
}
// Internal (This works)
func internalEnumIterator() {
for key in EnumA.all(EnumA.self) { internalCompletion(key) }
for key in EnumB.all(EnumB.self) { internalCompletion(key) }
for key in EnumC.all(EnumC.self) { internalCompletion(key) }
}
func internalCompletion<T: MyEnum>(_ key: T) where T: Hashable {
let value = "\(key)"
updateData(key, value)
}
// External (This obviously doesn't, just sketching the idea)
func externalEnumIterator(_ completer<T: MyEnum>: ((T) -> Void) where T: Hashable) {
for key in EnumA.all(EnumA.self) { completer(key) }
for key in EnumB.all(EnumB.self) { completer(key) }
for key in EnumC.all(EnumC.self) { completer(key) }
}
}
// MARK : - Test cases (internal works, external does not, just sketching example)
let iterator = MyDataEnumIterator()
iterator.externalEnumIterator({ <T: MyEnum> (T) where T: Hashable in
let value = "\(key)"
iterator.updateData(key, value)
})
iterator.internalEnumIterator()
物事を簡素化するために最小限の例を挙げてください。 – Alexander
これは非常に不必要に複雑です。これらのジェネリックは必要ありません。 – Alexander
私は知っています。私はジェネリック薬で遊んでいた。実際にはあなたのソリューションは明らかに優れています –