哪些编程语言在语言级别上支持状态?

4

UnrealScript 一直以来都给我留下了深刻的印象,它通过将函数和字段分组/重载成块的方式来支持状态(和潜在函数),这点非常优秀:

state() SomeState
{
    ...
    function void Foo()
    {
        GotoState('SomeOtherState');
    }
    ...
}

这比在每个函数中使用大量的switch语句要清晰得多(这几乎是一种按合同设计)。
是否有其他更通用的编程语言,支持类似于此的状态声明(忽略视觉编程语言或Workflow Foundation之类的工具)?
编辑:
UnrealScript中状态的一些优美之处在于您可以在子类中覆盖有状态的函数,甚至定义新的命名状态。我认为使用枚举开关(其中枚举无法扩展)、委托或实现不同状态的协同类,在C#或Java等仅支持单重继承的语言中进行此操作会很麻烦。

听起来很有趣。它与动态原型继承有什么不同? - jk.
10个回答

3

据我所知没有,但是支持元编程的语言(例如Ruby)可以通过元编程轻松编写领域特定语言。从Rails的acts_as_state_machine插件中可以看到:

class Nonprofit < ActiveRecord::Base
  acts_as_state_machine :initial => :created, :column => 'status'

  # These are all of the states for the existing system.
  state :submitted
  state :processing
  state :nonprofit_reviewing
  state :accepted

  event :accept do
    transitions :from => :processing,          :to => :accepted
    transitions :from => :nonprofit_reviewing, :to => :accepted
  end

  event :receive do
    transitions :from => :submitted, :to => :processing
  end

  # either a CTP  or nonprofit user edits the entry, requiring a review
  event :send_for_review do
    transitions :from => :processing,          :to => :nonprofit_reviewing
    transitions :from => :nonprofit_reviewing, :to => :processing
    transitions :from => :accepted,            :to => :nonprofit_reviewing
  end
end

(您还可以在事件块中包含任意代码,不仅限于状态转换)


3
任何面向对象的编程语言都可以轻松创建状态机。但是您可能希望看一下QT及其QT状态机框架。虽然我没有尝试过。
我更喜欢那些能让我创建各种支持结构的语言,而不是为所有不同类型的特殊情况提供特殊功能的语言。C++在QT中展示了这一点。

2

我所知道的编程语言中,没有一种能像UnrealScript中的“状态”一样提供相同的功能。在UnrealScript中,状态不像普通的状态机。它们更像是你可以放置在对象上方的层。这些层会拦截方法调用并访问对象的内部状态。

从UnrealEngine3开始,您还可以堆叠状态,因此可以有多个活动层。 例如:

function bar()
{ 
    // print quux
}

state S1
{
    function foo()
    { 
        // print foo
    }
}


state S2
{
    function foo()
    { 
        // print bar
    }


    function bar()
    { 
        // print bar
    }
}

现在,当您进入状态S2并调用foo()和bar()时,您将看到“bar bar”。当您从起始状态或S2转到状态S1并调用相同的方法时,您将看到“foo quux”。但是,当您在S2中将S1推入状态堆栈时,您调用foo()和bar()时将看到“foo bar”而不是“foo quux”。
无论如何,回到最初的问题。获得与UnrealScript提供的相同状态功能的一种方法是采用提供动态启用/禁用方面的AOP语言。

2

我并没有真正使用过UnrealScript,但你可以在任何支持一等函数/lambda的语言中实现相同的功能。


2
在Python中有boduch库,可以声明状态...但这不是内在的。

我还没有使用过它,但它似乎非常有前途,只是处于早期阶段。 - LB40


1
Lua也支持带状态的类,只要你愿意在Lua表的基础上进行编程。
或者,您可以使用我的库:MindState。我设计它以模仿UnrealScript的类系统和状态,从常规类继承到可堆叠状态。

1

我一直在想如何在C#中实现这个问题,尤其是因为我正在使用UnrealEngine 3作为设计自己的组件对象模型的基础。 (顺便说一句,UDK是原型功能的好方法。)除了使用像egarcia实现的外部方法(实际上可以通过LuaInterface在.NET中使用),我提出了两种可能性:

  1. 显式接口实现,每个状态一个接口。 然后将对象转换为相应的接口(即“状态”),并调用该方法; CLR会完成其余工作。 您甚至可以使用通用方法包装此调用,并将接口(“状态”)作为类型参数传递,但这可能有些繁琐。

  2. 创建以状态为键的字典,并将委托作为值。 在灵活性方面提供更大的灵活性,但看起来有点不靠谱。

就个人而言,从编码的角度来看,我更喜欢方法1,因为我全都是强类型,但是方法2更容易实现和更新。

顺便提一下,如果你对egarcia的Lua方法感兴趣,并认为LuaInterface对你来说太慢了,我已经修改了LuaInterface以支持LuaJIT。它使用本地导入,但希望LuaJIT的性能可以抵消调度调用。如果您需要源代码,请给我留言。

1

我知道的具有内在状态和状态机支持的编程语言通常分为两类:词法分析器专家系统

词法分析器通常面向文本处理,但通常可以适应其他用途。 词法分析器的示例包括(f)lexAntlrQuex。 我听说过人们使用lex来控制机器人的传说。

专家系统旨在基于一组规则和您提供的情况做出决策(据说像专家一样)。 实现其自己的状态处理语言的专家系统的示例是makeClips。 make旨在帮助构建软件,因此最好如果您对世界的看法可以基于文件日期。 Clips更加灵活,但本质上没有像make那样对外部操作系统有很好的视图。


1

我天真的理解是,“类型状态”为面向对象语言提供了这种功能:

什么是类型状态?

并且可以在任何支持特质的语言中轻松实现:

混入 vs 特质

不过,我还在学习所有这些知识,所以很想听听更有见地的答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接