Swift中的命令模式与struct的变异方法

时间:2015-07-28 08:45:05

标签: swift command-pattern

我试图了解如何在Swift中实现命令模式。到目前为止,这段代码运行良好:

class Subject
{
    var value: Int = 0

    func setValue(value: Int) {
        self.value = value
    }
}

class Command<T>
{
    private var receiver: T
    private var instructions: T -> Void

    init(receiver: T, instructions: T -> Void) {
        self.receiver = receiver
        self.instructions = instructions
    }

    func execute() {
        instructions(receiver)
    }
}

var subject = Subject()

println(subject.value) // "0"

let instructions: Subject -> Void = { sub in Subject.setValue(sub)(2) }
let command = Command<Subject>(receiver: subject, instructions: instructions)
command.execute()

println(subject.value) // "2"

但是,如果我希望接收器是struct而不是class,则相同的代码不起作用。因此,如果我将Subject定义为struct,如下所示:

struct Subject
{
    var value: Int = 0

    mutating func setValue(value: Int) {
        self.value = value
    }
}

然后我在let instructions: Subject -> Void = { sub in Subject.setValue(sub)(2) }上收到错误:“主题不能转换为inout主题”。

我不知道如何处理这个问题。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

问题是,如果要在对象上调用类方法,则需要传递inout参数。这是通过在变量前添加&来完成的:

Subject.setValue(&subject)(2)

但是,您无法在匿名方法中执行此操作,您需要明确地将其键入为inout参数。

我认为这段代码应该可行,但在我的情况下,它会崩溃Xcode playground和Xcode REPL:

struct Subject
{
    var value: Int = 0

    mutating func setValue(value: Int) {
        self.value = value
    }
}

class Command<T>
{
    private var receiver: T
    private var instructions: inout T -> Void

    init(inout receiver: T, instructions: inout T -> Void) {
        self.receiver = receiver
        self.instructions = instructions
    }

    func execute() {
        instructions(&receiver)
    }
}

var subject = Subject()

println(subject.value) // "0"


var instructions: inout Subject -> Void = { sub in Subject.setValue(sub)(2) }
let command = Command<Subject>(receiver: &subject, instructions: instructions)
command.execute()

println(subject.value) // "2"