4
let inline funA x =
    printf "A"
    x > 3

let inline funB myFun x =
    printf "B"
    myFun x

let foo () =
    funB funA 7

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

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

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

4

1 回答 1

4

我相信这个函数是内联的,只是不像你期望的那样。 funA只有当它有参数时才能内联。由于您没有funA在使用时提供参数,因此编译器将其视为fun x -> funA x并在其中内联funA- 因此创建了一个 lambda,就好像您编写了:

let foo() = 
    printf "B"
    (fun x -> 
        printf "A"
        x > 3) 7    
于 2013-07-29T14:14:23.870 回答