【问题标题】:How is a statement like let Select = Seq.filter compiled to CIL?像 let Select = Seq.filter 这样的语句是如何编译成 CIL 的?
【发布时间】:2013-11-18 21:01:57
【问题描述】:

我想知道一个语句是怎样的

 let Select = Seq.filter

被编译成 CIL:编译器是否内联对 Seq.filter 的调用? 有迹象表明这种假设是因为编译器抱怨:

 let inline Select = Seq.filter
 error FS0832: Only functions may be marked 'inline'

【问题讨论】:

  • Get Chocolatey,然后cinst ilspy,Windows,ILS,输入,您将得到答案,无需任何间接
  • 在 F# 中,inline 与由类型参数参数化的函数一起使用。见msdn.microsoft.com/en-us/library/vstudio/dd548047.aspx
  • @EugeneFotin - 这是典型的但不是必需的;如果您希望在使用站点内联非泛型函数,那么没有什么可以阻止您这样做。
  • 我只是想知道你们中的某个人是否马上就知道了答案。多年来我没有看 CIL 代码,我不确定我是否会通过阅读它得出正确的结论。顺便说一句:我写“Select”是因为我正在帮助一个朋友写一些看起来像 MATHEMATICA 的东西,他选择了大写。然后我选择了其中一行作为示例...
  • @SiegfriedStephan 重点是 ILSpy 将为您提供 VB 或 C#(或 IL)。 (尽管您的问题是有效的,但我仍然认为您不应该以任何方式认为加载 ILSpy 很难或很慢)

标签: f# inline cil


【解决方案1】:

我不认为你的推论是合乎逻辑的——编译器不是说,“你不能内联这个,因为它已经被内联了”,而是说,“你只能内联一个(句法)函数”(即也就是说,需要有语法参数,比如let inline select f = Seq.filter f)。

通常,编译器是否内联定义是一个实现细节,并且行为可能会根据您是在调试模式还是发布模式下编译而改变(有例外,例如可能产生副作用的定义,必须不要内联以保留语义,例如let f = printfn "blah"; fun x -> x,其中"blah" 只能打印一次)。如果您想查看特定版本的 F# 编译器做了什么,只需使用 ildasm 反汇编您的编译代码并查看一下。但也请记住,即使在 IL 中未内联,JIT 引擎也可能内联事物,因此这两种方式可能都不重要。

另外,作为一个小的风格说明,请记住,模块中的值和函数通常绑定到驼峰式标识符(所以 select,而不是 Select),而类型的成员遵循正常的 .NET 命名风格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2012-09-26
    • 2020-11-06
    • 1970-01-01
    • 2018-12-16
    相关资源
    最近更新 更多