我有一种情况,我想注册一个参数或无参数闭包与服务。总是有一个可用的参数,但为了简洁起见,我希望能够不注册arg闭包,然后在没有可用参数的情况下分派闭包。从一个强大的面向对象的动态类型的背景,我们爱态分派和类继承的树木,让类型图自己出的到来,我可以扔在一起以下几点:与结构/协议的Swift多态闭包调度
class AbstractAction<T> {
func publish(value:T) {
fatalError("you should override this")
}
}
class NullaryAction<T>: AbstractAction<T> {
var closure:() ->()
override func publish(_:T) {
closure()
}
init(closure:()->()) {
self.closure = closure
}
}
class UnaryAction<T>: AbstractAction<T> {
var closure:(T) ->()
override func publish(value:T) {
closure(value)
}
init(closure:(T)->()) {
self.closure = closure
}
}
var action:AbstractAction = UnaryAction<Int>(closure: { print("\($0)") })
action.publish(42)
action = NullaryAction<Int>(closure: { print("something happened") })
action.publish(42)
所以我看到后面something happened
在我的控制台42
。大。
但我想探索与struct
和/或enum
这样做。价值语义是所有的愤怒。该enum
方法是相对简单的,我认为:
enum Action<T> {
case Nullary(()->())
case Unary((T)->())
func publish(value:T) {
switch self {
case .Nullary(let closure):
closure()
case .Unary(let closure):
closure(value)
}
}
}
var action = Action.Unary({ (arg:Int) ->() in print("\(arg)") })
action.publish(42)
action = Action<Int>.Unary({ print("shorthand too \($0)") })
action.publish(42)
action = Action<Int>.Nullary({ print("something happened") })
action.publish(42)
做一个struct
办法,我这是我的理解,我应该使用协议捕捉publish(value:T)
通用接口。但这就是事情变得混乱的地方,因为协议显然不能与泛型混合在一起?我试过了:
struct NullaryAction<T> {
typealias ValueType = T
var closure:() ->()
}
struct UnaryAction<T> {
typealias ValueType = T
var closure:(T) ->()
}
protocol Action {
typealias ValueType
func publish(value:ValueType)
}
extension NullaryAction: Action {
func publish(_:ValueType) {
self.closure()
}
}
extension UnaryAction: Action {
func publish(value:ValueType) {
self.closure(value)
}
}
var action:Action = UnaryAction(closure: { (arg:Int) ->() in print("\(arg)") })
action.publish(42)
action = UnaryAction<Int>(closure: { print("shorthand too \($0)") })
action.publish(42)
action = NullaryAction<Int>(closure:{ print("something happened") })
action.publish(42)
这只是在底部产生了很多错误。我试图将扩展名作为泛型(例如extension NullaryAction<T>:Action
),但它告诉我T
未被使用,即使我已将typealias
表达式放入扩展中。
是否有可能使用struct/protocol做到这一点?我对enum解决方案感到满意,但对使用struct/protocol方法无法实现它感到失望。
Swift中的协议和泛型可能非常棘手。也许这个线程的答案可以帮助你:http://milen.me/writings/swift-generic-protocols/(另请参见forums.developer.apple.com/thread/7350)。然而,这两者都与一些协议函数的泛型返回类型有关,但也许你可以使用动态类型的魔法来解决某些问题:)我有兴趣知道结果,对于您的具体示例(尝试修复某些内容但失败相当悲惨......) – dfri