2016-10-20 2 views
2

Я новичок в Swift, и я хотел бы знать, имеет ли язык какой-то эквивалент рисунка декоратора Python.
Например:Декораторы в Swift

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 

Может быть, я просто не нашел еще, но Swift, кажется, не есть способ направить произвольные аргументы функций или для сохранения информации обернутой функции (как functools.wraps делает).

Есть ли эквивалент или шаблон, который не предназначен для использования в Swift?

ответ

2

Вы можете использовать это:

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 

Или announce как функции вместо закрытия, позволяя повторное использование:

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 
Смежные вопросы