【问题标题】:What can a run-time reflection do that a compile-time one cannot?运行时反射能做什么而编译时反射不能?
【发布时间】:2014-07-29 05:21:36
【问题描述】:

我看到一些观点认为,Rust 和 M# 可能会选择编译时反射,因为运行时反射很昂贵并且会增加二进制文件的大小。到目前为止,我找不到任何好的比较,只是一些意见认为运行时反射“很少是一个好主意”。似乎探索内置编译时反射概念的语言都还在开发中。

目前我读过的资料:

【问题讨论】:

  • 我会稍微澄清一下我在最后提到的来源中所说的话:从概念上来说,我认为运行时反射不如编译时反射。我是作为一个主要是 Python 开发人员的人说的,尽管我现在在自己的时间里写了很多 Rust。在实践中,大多数语言没有足够强大的编译时语义,因此大多数时候编译时反射是不够的。
  • 我认为您可能会在这里得到答案,一个足够强大的编译器实际上可以让您使用编译时反射。我不相信这对 Stack Overflow 来说是一个特别好的问题,但让我们看看它是怎么回事。如果可以的话,我会随时反驳任何说法!
  • @ChrisMorgan 我有疑问,但我觉得这个问题可以通过以下方式得到最终回答:“动态加载二进制文件,然后实例化标有特定注释的 any 类型然后以某种方式处理标记有另一个注释的所述实例的所有字段”。答案将对狭窄类型的项目(我猜主要是框架:ORM、插件驱动的编辑器(又名 Unity3d)等)产生实际影响。
  • 这不是我认为需要运行时反射的东西。考虑一下 Rust 编译器如何支持加载外部语法扩展——这是通过找到库文件到 dlopen,从预定位置加载在编译时标记在其中的函数,然后调用它来完成的。除此之外没有反射,因为它使用特征对象。特征和特征对象(动态分派)消除了这种运行时反射的必要性,因此仍然需要能够链接到动态确定的库。

标签: reflection runtime introspection rust compile-time


【解决方案1】:

这是一些 Ruby:

m = STDIN.gets.chomp

puts Object.respond_to?(m)

在编译时不可能做到这一点。我的意思是,使用CTFE,您可以技术上在编译时运行此代码,但作为正在运行的程序的一部分,它不会真正起作用。

另一个有趣的:

$m = STDIN.gets.chomp

class Object
   define_method $m do
     puts "zomg"
   end
end

class Foo; end

Foo.new.send($m)

这会打印“zomg”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2012-03-09
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多