【问题标题】:Constructor parameter validation code doesn't compile构造函数参数验证代码无法编译
【发布时间】:2021-11-25 03:55:18
【问题描述】:

我正在尝试在 F# 中编写一个带有一些基本参数验证的简单抽象类:

[<AbstractClass>]
type Record(recordType: int16) =
    let recordType: int16 = recordType

    do
        if recordType < 0s then
            invalidArg (nameof recordType)

但是,我在最后一行遇到错误:“this if expression is missing an else branch。”我尝试添加一个仅计算为 null 的 else 分支,但随后类型系统与我的代码不一致。难道我做错了什么?我应该使用其他方法来验证我的论点吗?

【问题讨论】:

    标签: class validation constructor f# arguments


    【解决方案1】:

    问题在于 invalidArg 需要一个参数名称(您已将其作为 nameof recordType 传递,以及您留下的错误消息,并且您的 if 分支返回一个函数(string -&gt; 'a 作为返回由于抛出异常,类型未知/无法访问)。

    如果您查看docs for invalidArg,您会看到:invalidArg parameter-name error-message-string。您的代码实际上是这样的:

    // This is a function: string -> 'a (as it raises an exception, the return type is unknown)
    let partialInvalidArg = invalidArg (nameof recordType)
    if recordType < 0s then
        partialInvalidArg // You're returning a function, not unit, so the compiler complains
    

    如果你包含错误信息,该函数实际上是在分支中调用的,这将编译正常:

    [<AbstractClass>]
    type Record(recordType: int16) =
        let recordType: int16 = recordType
    
        do
            if recordType < 0s then
                invalidArg (nameof recordType) "The recordType must be greater or equal to zero"
    

    【讨论】:

    • 啊,我没有意识到它需要 2 个参数。我完全不考虑咖喱;不幸的是,它有时会使错误消息更加混乱。
    猜你喜欢
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多