使用内联中间语言
使用内联中间语言(Inline IL)
内联中间语言(Inline IL)直接在中间语言(intermediate language,IL)定义的函数体,中间语言 F# 编译语言,这主要是为了语言添加到达到一个较低的比运算符和函数。实例,加法和box 和 not 的功能。我们非常少会用到这个功能,由于F# 库FSharp.Core.dll 已经公开了全部的、可能须要的生成中间语言的功能。然而,有一些极为罕见的情况。不能在 F# 中完毕,而仅仅能在中间语言中实现。内联中间语言是非常好的选择。
使用内联中间语言非常easy。仅仅要把中间语言指令放在括号和#号中间,(# #)。
中间语言指令放在字符串中间,使用可以被ilasm.exe 编译的标准记号,它必须是正确的中间语言形式,否则会编译出错;然后,传递參数给中间语言指令,它们被压入中间语言评估栈(IL evaluation stack)中;还必须使用标准的冒号。告诉编译器返回的类型是什么。这要放在括号里间;还须要显式地指定參数类型。由于编译器没有办法出它们的类型。
我们如今看一下使用内联中间语言的演示样例。
如果因为某种原因,我们要使用在 F# 基本库fslib.dll 中定义的加法和减法运算符。用我们自定义的函数去替换它们。
我们定义了两个函数add 和 sub,函数体使用中间语言定义:
// declare add functionusing the IL add instruction
let add (x:int)(y:int) = (# "add"x y : int #)
// declare sub functionusing the IL sub instruction
let sub (x:int)(y:int) = (# "sub"x y : int #)
// test these functions
let x = add 1 1
let y = sub 4 2
// print the results
printfn "x: %i y:%i" x y
演示样例的执行结果例如以下:
x: 2 y: 2
程序猿应该小心使用这样的方法,由于写一个毫无意义的程序并不重要,编译器不可能为此而发出警告。
考虑以下的的程序,我们改动了一下前面的演示样例,把 "add" 指令替换成 "ret" 指令,表示是返回值,在这个上下文中没有意义。这个演示样例在编译时没有错误和警告,可是执行时会出错。
// create a faulty add function
let add (x:int) (y:int) = (# "ret"x y : int #)
// attempt to use fault function
let x = add 1 1
演示样例的执行结果例如以下:
Unhandled Exception: System.InvalidProgramException:Common Language Runtime
detected an invalid program.
at Error.add(Int32 x, Int32 y)
注意
随.NET SDK 公布的一个工具可以帮助检測这样的错误。这个工具叫peverify.exe,很多其他信息有关此工具。也可以看看http://msdn2.microsoft.com/en-us/library/62bwd2yd(vs.80).aspx。