2016-10-20 7 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が行うようスウィフトは(関数に任意の引数を転送するか、包まれた機能の情報を保存する方法を持っていないようです)。

相当品がありますか、または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