2016-10-20 5 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 

아마도 내가 아직 그것을 발견하지 않은,하지만 functools.wraps이처럼 스위프트 (함수에 임의의 인수를 전달하는 또는 포장 기능의 정보를 보존 할 수있는 방법이 보이지 않는다).

동급입니까 또는 스위프트에서 사용하지 않는 패턴입니까?

답변

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