我正在尝试使用枚举来包含通用函数。这些枚举将作为参数传递,然后可以相应地执行枚举中的函数。
如何在枚举定义中设置泛型类型,以便将它们识别为要执行的函数?请注意,我可能想要传入各种函数定义。
如果我在这里很荒谬,请告诉我。 :)
// Define an enum to pass into my APIs. The S and F are meant to be functions I can define in anyway
enum FormattedResult<S, F> {
case Success(S)
case Failure(F)
func run<T> (a:T) {
switch (self){
case .Success (let completion):
// QN: How do I execute this? completion() will of course fail
debugPrint(completion)
case .Failure (let failure):
// QN: Same here
debugPrint(failure)
}
}
}
// I want to define a callback for someone else to call. I will be passing this to the error
var k1 = FormattedResult<(Int)-> (), (String)->() >.Success(
{(a: Int) in
debugPrint("xxxxx")
})
// the APIClient can run this upon completion
k1.run(2)
// similarly for failures
var k2 = FormattedResult<(Int)-> () , (String)->()>.Failure(
{(error: String) in
debugPrint(error)
}
)
k2.run("some error happened...")
最佳答案
在原始代码中,虽然在创建变量k1
或k2
时定义了一个闭包作为回调,但是S
和F
仍然只是占位符类型,并没有说明 S
和 F
必须是什么。因此,这里的挑战是如何定义 Swift 枚举来存储给定函数类型的关联值。
所以我们的想法是我们可以使用诸如 (T) -> void
之类的函数类型作为枚举的参数类型,并将函数实现的某些方面与枚举案例值一起留给 when enum 函数被调用。
接下来我们不需要在枚举中使用两种占位符类型,因为每次调用函数 run(:)
时我们只有一种类型的 a
即使它可能是 String
或 Int
。这也是 Generic
的强大之处。虽然占位符类型 T
没有说明 T
必须是什么,但它确实说明了 a
和枚举的关联值 (T) -> void
必须是同一类型 T,无论 T 代表什么。因此,在这种情况下,一种类型的占位符就足够了。
实际上,我喜欢您的想法,即调用者可以传入一个值以由枚举中的 run 函数执行,并且您在原始代码中几乎做到了。以下是我上面提到的一个例子。
enum FormattedResult<T> {
case Success(((T) -> Void))
case Failure(((T) -> Void))
func run(a:T) {
switch self {
case Success(let completion):
completion(a)
case Failure(let completion):
completion(a)
}
}
}
let f1 = FormattedResult.Success({ a in
debugPrint(a)
})
f1.run(1)
let f2 = FormattedResult.Failure({ error in
debugPrint(error)
})
f2.run("some error happened...")
关于swift - 在枚举中使用泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35761261/