let inline funA x =
printf "A"
x > 3
let inline funB myFun x =
printf "B"
myFun x
let foo () =
funB funA 7
IL foo
.method public static
bool foo () cil managed
{
// Method begins at RVA 0x2278
// Code size 31 (0x1f)
.maxstack 4
.locals init (
[0] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>
)
IL_0000: nop
IL_0001: ldstr "B"
IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string)
IL_000b: stloc.0
IL_000c: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out()
IL_0011: ldloc.0
IL_0012: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatToTextWriter<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
IL_0017: pop
IL_0018: ldc.i4.7
IL_0019: call bool Foo::myFun@21(int32) // Here!
IL_001e: ret
} // end of method Foo::foo
IL myFun@21
.method assembly static
bool myFun@21 (
int32 x
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x224c
// Code size 29 (0x1d)
.maxstack 4
.locals init (
[0] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>
)
IL_0000: ldstr "A"
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string)
IL_000a: stloc.0
IL_000b: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out()
IL_0010: ldloc.0
IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatToTextWriter<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
IL_0016: pop
IL_0017: nop
IL_0018: ldarg.0
IL_0019: ldc.i4.3
IL_001a: cgt
IL_001c: ret
} // end of method Foo::myFun@21
IL funA
.method public static
bool funA (
int32 x
) cil managed
{
// Method begins at RVA 0x2218
// Code size 22 (0x16)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "A"
IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string)
IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormat<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
IL_0010: pop
IL_0011: ldarg.0
IL_0012: ldc.i4.3
IL_0013: cgt
IL_0015: ret
} // end of method Foo::funA
正如您所看到的,myFun@21
几乎与funA
完全相同,我不明白为什么它存在。为什么函数没有内联?是因为我将一个函数作为参数传递给另一个函数吗?在这种情况下,我认为没有任何难以解决封闭的事情使其无法内联。
是否有任何资源可以让我更多地了解函数何时被标记为inline
而无法内联?
答案 0 :(得分:3)
我相信这个功能是内联的,而不是你想象的方式。 funA
只有在有参数的情况下才能内联。由于您没有在使用时向funA
提供参数,编译器会将其视为fun x -> funA x
并在那里内联funA
- 因此创建了一个lambda,就好像你写的那样:
let foo() =
printf "B"
(fun x ->
printf "A"
x > 3) 7