SWIFT中的Curried功能

时间:2014-12-25 06:15:54

标签: swift

阅读Ole的帖子http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/

我的理解是你可以在不同的上下文或范围内调用任何类的方法。如果我理解正确,那么它与javascript中的applycall相同。

这是我尝试将其用于观察者模式。

我在self.method(self.context)(message)中遇到问题,错误显示为(Messaging) -> $T6 is not identical to 'Void'

protocol Messaging {
    var message: String { get set }
}

class Observer {
    var method: Messaging -> Void
    var context: AnyObject

    init(method: Messaging -> Void, context: AnyObject) {
        self.method = method
        self.context = context
    }

    func notify(message: Messaging) {
        self.method(message)
        //self.method(self.context)(message) // Houston, we have a problem
    }
}

public class Message: Messaging {
    var message: String

    public init(message: String) {
        self.message = message
    }
}

class TestObserver {

    func createAndNotifiy() {
        var observer = Observer(method: self.handleMessage, context: self)
        observer.notify(Message(message: "TestMessage"))
    }

    func handleMessage(message: Messaging) -> Void {
        println(message.message)
    }
}

var test = TestObserver()
test.createAndNotifiy()

notify方法内我试图在传递的上下文中调用传递的方法(我已将context用作self,但它可能是不同的上下文太)

我的目标是让它适用于传入的任何上下文。

编辑:这是我传入的功能,它会自动与该上下文相关联,例如Observer(method: self.handleMessage...在这种情况下handleMessage是在这种情况下隐式/显式绑定到self并且我不应该真正关心将self作为附加参数传递(作为上下文),因为self.method(message)调用method在绑定对象的上下文中自动?这是我的假设,期待一个坚实的意见。

但无论如何还想知道如何在这种情况下让咖喱方法起作用

1 个答案:

答案 0 :(得分:1)

self.methodname(您使用的)和Classname.methodname之间存在差异。

前者在类的方法中调用时,会给你一个与该类实例绑定的函数。因此,如果你调用它,它将在该实例上调用。

后者为您提供了一个curried函数,它将Classname的任何实例作为参数,并返回绑定到该实例的新函数。此时,该功能与第一种情况类似(只有您可以将其绑定到您喜欢的任何实例)。

这是一个尝试显示更好的例子:

class C {
    private let _msg: String
    init(msg: String) { _msg = msg }

    func print() { println(_msg) }

    func getPrinter() -> ()->() { return self.print }
}

let c = C(msg: "woo-hoo")
let f = c.getPrinter()
// f is of type ()->()
f() // prints "woo-hoo"

let d = C(msg: "way-hey")

let g = C.print
// g is of type (C)->()-(),
// you need to feed it a C:
g(c)() // prints "woo-hoo"
g(d)() // prints "way-hey"

// instead of calling immediately,
// you could store the return of g:
let h = g(c)
// at this point, f and h amount to the same thing:
// h is of type ()->()
h() // prints "woo-hoo"

最后,看起来你正在尝试使用AnyObject来接受任何类的类并将其传递给你的curried实例方法。那将不会飞 - 那个curried方法将特别需要一种类型的类。没法好尝试用别的东西喂它。