F#内联如何工作?

Mic*_*l B 14 c# f# inline

使用F#,我理解您可以使用inline关键字在呼叫站点执行类型特化.那是::

val inline (+) : ^a -> ^b -> ^c
      when (^a or ^b) : (static member (+) : ^a * ^b -> ^c)
Run Code Online (Sandbox Code Playgroud)

约束,^a或者^b必须有一个静态成员op_Addition,或者一个内置的原语,可以用来填补空白.

因此,如果你有一个方法有一个+,你传入一个int和一个short作为参数,它解包+指令使用内置的原语为int,如果你传入一个浮点数和一个字节,它使用浮点数原始加法操作码.

这在编译时是如何完成的?你怎么能在CLR中有一个方法根据类型切换它使用的操作码或方法?

Reflection.Emit可以实现这种行为吗?我理解内联是在调用站点执行的,这是否意味着代码不能与C#一起使用?

Bri*_*ian 10

如建议的那样inline,代码在呼叫站点处内联.在每个调用站点,您都知道具体的类型参数^T,因此在那里插入该类型的特定代码.

这是由F#编译器完成的,你不能轻易地在其他上下文中完成它(比如C#或Ref.Emit).

在F#库有仍然可以通过其他语言调用一些内联函数,对于那些实现运行时不根据运行时类型的动态调度,例如见的代码AdditionDynamicprim-types.fs的F#核心库代码来感受.

  • 任何类型`FSharpFunc`(或实际上大多数类型)的实例都不是(也不能)是`inline`.`inline`适用于方法和函数,而F#库中只有少数几个适用.大多数东西可以从C#中调用,但是一些不支持动态调用的F#`inline`函数(如`sin`)只能从F#调用,因为F#编译器必须在调用站点内联代码. (2认同)