【问题标题】:Command pattern in Swift with struct's mutating methodsSwift 中的命令模式与结构的变异方法
【发布时间】:2015-10-18 17:17:55
【问题描述】:

我正在尝试了解如何在 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 -&gt; Void = { sub in Subject.setValue(sub)(2) } 上的“主题不可转换为 inout 主题”。

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

【问题讨论】:

  • 这可能很困难。请注意,Command init 方法中的self.receiver = receiver 已经制作了结构的独立副本。
  • 如此真实......这让我想到如果我因为糟糕的设计理念而遇到这个问题。一般而言,将命令模式应用于结构(“值”)对象(?)也许没有多大意义(?)谢谢!

标签: swift command-pattern


【解决方案1】:

问题是,如果你想在一个对象上调用一个类方法,你需要传递一个 inout 参数。这是通过在变量前面附加一个&amp; 来完成的:

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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-19
    • 2012-02-10
    • 2022-12-10
    • 2010-11-21
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    相关资源
    最近更新 更多