サービスに引数クロージャを 1 つ登録するか、引数クロージャを登録しない場合があります。利用可能な引数は常にありますが、簡潔にするために、arg クロージャーも登録せず、その場合は利用可能な引数なしでクロージャーをディスパッチできるようにしたいと考えています。強力な OO と動的型のバックグラウンドから来て、ポリモーフィック ディスパッチとクラス継承ツリーが大好きで、型自体が理解できるようにすることで、次のことをまとめることができます。
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)
そのため、コンソールに42
続いて表示されます。something happened
偉大な。
struct
しかし、 and/orを使用してこれを行うことを検討したいと思い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
ました。
構造体/プロトコルでこれを行うことは可能ですか? 列挙型ソリューションには満足していますが、構造体/プロトコルのアプローチでは実現できなかったことに失望しました。