F#参数检查
F#有一些很好的简洁的参数检查函数,可以这样使用:F#参数检查,f#,arguments,code-contracts,design-by-contract,quotations,F#,Arguments,Code Contracts,Design By Contract,Quotations,F#有一些很好的简洁的参数检查函数,可以这样使用: let foo (bar : string) : string = if bar = null then nullArg "bar" ... open Microsoft.FSharp.Quotations let nonNull (expr : Expr) = match expr with | Patterns.Value(null, _) -> failwith "it is null"
let foo (bar : string) : string =
if bar = null then
nullArg "bar"
...
open Microsoft.FSharp.Quotations
let nonNull (expr : Expr) =
match expr with
| Patterns.Value(null, _) -> failwith "it is null"
| _ -> ()
然而,我更喜欢一种更具规定性的表达方式,即la代码:
let foo (bar : string) : string =
Contract.Requires (bar <> null, "bar is null")
...
let foo(条:字符串):字符串=
合同。要求(栏为空,“栏为空”)
...
然而,我梦想编写的代码是:
let nonNull (expr : Expr) : unit =
// quotation magic
let foo (bar : string) : string =
nonNull <@ bar @>
...
设为非空(expr:expr):单位=
//引文魔术
让foo(bar:string):string=
非空
...
问题是:这能用F表示吗;或者换句话说,F#中是否有非null的有效实现
对我来说,它看起来不像,但也许这里有人可以验证它。正如@svick在评论中提到的,这目前不会很好地工作,因为
实际上将表示为值(null,typeof)
。因此,您可以检查该值是否为null
,但当前无法获取参数的名称
您可以执行的部分如下所示:
let foo (bar : string) : string =
if bar = null then
nullArg "bar"
...
open Microsoft.FSharp.Quotations
let nonNull (expr : Expr) =
match expr with
| Patterns.Value(null, _) -> failwith "it is null"
| _ -> ()
但是,这在下一个版本中可能会有所改进:-)这需要能够在引号中表示变量的名称。因此,也许可以使用下一个版本的F# 我认为这是行不通的。引号
不包含任何有关参数名称的信息。动机是什么?@MarkSeemann动机是函数契约的简洁、精确的表达。@BentRasmussen的确,这是吹毛求疵,但是如果bar=null,则空值“bar”
有32个字符,而契约.Requires(bar null,“bar为空”)
有46个字符,所以我看不出它为什么没有那么紧凑。一般来说,.NET没有像埃菲尔那样的断言……不是答案,只是有切点关系,但有这个方向的东西,因此很有趣(除此之外,@TomasPetricek指出,这一切都取决于报价是否有足够的信息被隐藏)好吧,好吧,很高兴看到其他人也有类似的想法。:-)谢谢你的回答,托马斯。既然这是目前最好的答案,我将把它标记为答案(并对用户声音进行投票)。