【发布时间】:2015-09-11 04:23:42
【问题描述】:
正如标题所说,我试图将一些命令存储在我正在编写的程序(代码生成器)中,只是为了在稍后阶段解释它们。
这主要是因为某些命令需要其他命令的信息,我认为最好不要对命令发送者强制执行非常严格的命令(尽管这种选择也有使其更难的缺点来决定一个命令是否无效)。
这个问题非常简单:在 Scala 中,除了 Buffer 之外,我想不出任何其他集合来表示这个命令队列。在我的情况下不需要并发,使用一次更新一个元素的不可变集合感觉很愚蠢。
另一方面,无论如何,我想在我的程序中尽可能减少可变性 - 这是一个可以合理完成的地方吗?或者我的直觉是正确的,而 Buffer 很适合我的情况..
这是使用不可变集合时此商店的外观示意图。 (终止命令表示我们已完成对给定符号的更新,然后可以通过解释其唯一的 BuildCommand 以及零个或多个 UpdateCommands 来构建它)
trait Outcome
sealed trait Command {
def symId : String
}
sealed trait ChangeCommand extends Command
sealed trait BuildCommand extends Command
sealed trait UpdateCommand extends Command
final case class TerminationCommand(symId: String) extends Command
var comQueue = immutable.Seq[ChangeCommand]()
private def translate(sId : String) : Outcome = {
val forSymb = comQueue filter {_.symId}
//...
}
def interpret(c : Command) = c match {
case cc : ChangeCommand =>
comQueue = comQueue + cc
None
case TerminationCommand(s) =>
Some(translate(s))
}
【问题讨论】:
-
我必须指出,大多数不可变集合在追加时不会复制整个内容,它们共享大量数据(它们可以共享,因为一切都是不可变的)。在注销之前做一些分析。我喜欢矢量。
-
@experquisite 效率不是我主要关心的问题。我主要说“如果感觉很傻”,因为不可变集合将涉及使用丑陋的 var。并且会创建很多中间集合(无论是否轻量级),这让我感觉有些浪费
-
如果您正在执行命令式循环,它只会涉及 var 吗?听起来您可以展开成不可变的 Seq?
-
@experquisite 好的,我已经编辑了帖子并添加了一些代码(如果没有它,我的问题太枯燥了,很抱歉)。你能避免这里的 var 吗?命令一次一个(例如“将数组 x 值设置为 5”)
-
为什么你不能有
interpret(Seq[ChangeCommand], Command) => (Seq[ChangeCommand], Option[Outcome])这样你就不会在这里有任何状态,而且作为奖励,单元测试真的很容易。
标签: scala functional-programming