我可以使用泛型协议来描述非泛型类型的委托吗?
Can I use a generic protocol to describe a delegate in a non generic type?
我正在尝试使用通用协议描述委托 属性,而不使 class 通用:
protocol ActionHandler: class {
associatedtype Action
func handle(_ action: Action)
}
enum SomeAction {
case dismiss
}
class Foo {
typealias Action = SomeAction
// Protocol 'ActionHandler' can only be used as a generic constraint because it has Self or associated type requirements
weak var handler: ActionHandler?
// Ideally some form of ActionHandler<Action>?
}
class Handler: ActionHandler {
func handle(_ action: SomeAction) {
switch action {
case .dismiss:
print("dismiss")
}
}
}
let handler = Handler()
Foo().handler = handler
我可以用闭包代替 属性,但我不太喜欢这种模式,对于协议中描述的每个方法我都必须这样做。
enum SomeAction {
case dismiss
}
class Foo {
typealias Action = SomeAction
var handleAction: ((Action) -> Void)?
}
class Handler {
func handle(_ action: SomeAction) {
switch action {
case .dismiss:
print("dismiss")
}
}
}
let handler = Handler()
Foo().handleAction = handler.handle(_:)
有更好的解决方案吗?
您 没有 使 Foo
通用,但您需要一个很好的理由不这样做。无论如何,这是一种建立在闭包方法之上的方法——如果我们将这些闭包包装在一个类型中会怎样?
class AnyActionHandler<Action> : ActionHandler {
var handleClosure: (Action) -> Void
func handle(_ action: Action) {
handleClosure(action)
}
init<ActionHandlerType: ActionHandler>(_ actionHandler: ActionHandlerType) where ActionHandlerType.Action == Action {
handleClosure = actionHandler.handle(_:)
}
}
现在如果 ActionHandler
中有更多的方法,你可以只添加到这个类型中,而不是在你分配给 Foo.handler
的地方添加它们。 Foo
可以刚好有
weak var handler: AnyActionHandler<Action>?
分配处理程序如下所示:
Foo().handler = AnyActionHandler(handler)
这种AnyActionHandler
类型称为“类型橡皮擦”。
我正在尝试使用通用协议描述委托 属性,而不使 class 通用:
protocol ActionHandler: class {
associatedtype Action
func handle(_ action: Action)
}
enum SomeAction {
case dismiss
}
class Foo {
typealias Action = SomeAction
// Protocol 'ActionHandler' can only be used as a generic constraint because it has Self or associated type requirements
weak var handler: ActionHandler?
// Ideally some form of ActionHandler<Action>?
}
class Handler: ActionHandler {
func handle(_ action: SomeAction) {
switch action {
case .dismiss:
print("dismiss")
}
}
}
let handler = Handler()
Foo().handler = handler
我可以用闭包代替 属性,但我不太喜欢这种模式,对于协议中描述的每个方法我都必须这样做。
enum SomeAction {
case dismiss
}
class Foo {
typealias Action = SomeAction
var handleAction: ((Action) -> Void)?
}
class Handler {
func handle(_ action: SomeAction) {
switch action {
case .dismiss:
print("dismiss")
}
}
}
let handler = Handler()
Foo().handleAction = handler.handle(_:)
有更好的解决方案吗?
您 没有 使 Foo
通用,但您需要一个很好的理由不这样做。无论如何,这是一种建立在闭包方法之上的方法——如果我们将这些闭包包装在一个类型中会怎样?
class AnyActionHandler<Action> : ActionHandler {
var handleClosure: (Action) -> Void
func handle(_ action: Action) {
handleClosure(action)
}
init<ActionHandlerType: ActionHandler>(_ actionHandler: ActionHandlerType) where ActionHandlerType.Action == Action {
handleClosure = actionHandler.handle(_:)
}
}
现在如果 ActionHandler
中有更多的方法,你可以只添加到这个类型中,而不是在你分配给 Foo.handler
的地方添加它们。 Foo
可以刚好有
weak var handler: AnyActionHandler<Action>?
分配处理程序如下所示:
Foo().handler = AnyActionHandler(handler)
这种AnyActionHandler
类型称为“类型橡皮擦”。