例外只是高级非本地流控制构造的更一般情况的一个特定示例。其他示例是:
- 通知 (异常的概括,最初来自某些旧的Lisp对象系统,现在在CommonLisp和Ioke中实现),
- 延续 (结构化的形式
GOTO
,在高级,高阶语言中流行), - 协程 (子程序的泛化,在Lua中尤其流行),
- __Python的 生成器 (本质上是协程的一种受限形式),
- 纤维 (轻巧的合作纱线),当然已经提到
GOTO
。
(我肯定还有很多其他的我想念的。)
这些构造的一个有趣的特性是它们的表达能力大致相同:如果您拥有 一个 ,则可以很容易地构建所有其他构造。
因此,如何最好地实现异常取决于可用的其他构造:
- 每个CPU都有
GOTO
,因此,如果必须的话,您总是可以退一步。 - C具有
setjmp
/longjmp
基本上是MacGyver的延续(由胶带和牙签制成,不是很真实,但是如果没有更好的选择,至少可以使您摆脱直接的麻烦)。 - JVM和CLI具有自己的异常,这意味着,如果您语言的异常语义与Java / C#匹配,则您可以自由使用(但如果不匹配,则很麻烦)。
- Parrot VM作为例外和延续。
- Windows有其自己的异常处理框架,语言实现者可以使用该框架在顶部构建自己的异常。
一个非常有趣的使用情况,无论是的 使用 异常 ,并 在 实施
例外的是微软Live实验室的沃尔特项目。(现在不存在了。)Volta的目标是只需按一下按钮即可为Web应用程序提供体系结构重构。因此,只需将一些
[Browser]或
[DB]属性放在.NET代码中,就可以将一层Web应用程序转换为两层或三层应用程序,然后这些代码将自动在客户端或数据库中运行。为此,显然必须将.NET代码转换为Javascript源代码。
现在,您 可以 使用Javascript编写整个VM,然后运行未修改的字节码。(基本上,将CLR从C
++移植到Javascript。)实际上,有一些项目可以做到这一点(例如HotRuby VM),但这既效率低下又不能与其他Javascript代码互 *** 作。
因此,他们写了一个编译器,将CIL字节码编译为Javascript源代码。但是,Javascript缺少.NET所具有的某些功能(生成器,线程,还有两个异常模型不是100%兼容的),更重要的是,它缺少编译器编写者
喜欢的 某些功能(可以是
GOTO或延续的),并且可以用来实现上述缺少的功能。
但是,Javascript 确实 有例外。因此,他们使用 Javascript异常 来实现 Volta Continuations ,然后使用
Volta Continuations 来实现 .NET Exceptions , .NET Generators 甚至是 .NET
Managed Threads (!!!)
因此,回答您的原始问题:
幕后如何实施例外?
具有例外的是,具有讽刺意味的是!至少在这种非常特殊的情况下。
另一个很好的例子是Go邮件列表中的一些异常建议,它们使用Goroutines(类似于并发协程和CSP进程的混合物)实现异常。还有一个例子是Haskell,它使用Monads,惰性求值,尾部调用优化和高阶函数来实现异常。一些现代CPU还支持异常的基本构建块(例如,专门为Azul
Systems Java Compute Accelerator设计的Vega-3 CPU)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)