Decorators in Swift
composition, decorator, swift
Solution
You can use this:
func decorate<T, U>(_ function: @escaping (T) -> U, decoration: @escaping (T, U) -> U) -> (T) -> U {
return { args in
decoration(args, function(args))
}
}
let add: (Int, Int) -> Int = decorate(+) { args, rv in
print("In: \(args)")
print("Out: \(rv)")
return rv
}
add(2, 5) // In: (2, 5)\nOut: 7
Or `announce` as function instead of closure, allowing reuse:
func announce<T, U>(input args: T, output rv: U) -> U {
print("In: \(args)")
print("Out: \(rv)")
return rv
}
let add: (Int, Int) -> Int = decorate(+, decoration: announce)
add(2, 5) // In: (2, 5)\nOut: 7
let length = decorate({(str: String) in str.characters.count }, decoration: announce)
length("Hello world!") // In: Hello world!\nOut: 12
Problem
I'm new to Swift, and I'd like to know if the language has some equivalent to Python's decorator pattern. For example: ``` import functools def announce(func): """Print a function's arguments and return value as it's called.""" @functools.wraps(func) def announced_func(*args, **kwargs): rv = func(*args, **kwargs) print('In: {0}, {1}'.format(args, kwargs)) print('Out: {}'.format(rv)) return rv return announced_func @announce # add = announce(add) def add(a, b): return a + b add(2, 5) # In: (2, 5), {} # Out: 7 # 7 ``` Perhaps I just haven't found it yet, but Swift doesn't seem to have a way to forward arbitrary arguments to functions or to preserve a wrapped function's information (as functools.wraps does). Is there an equivalent, or is the pattern not meant to be used in Swift?