【问题标题】:Cannot create list literal in F#无法在 F# 中创建列表文字
【发布时间】:2015-03-30 14:40:12
【问题描述】:

我有以下几种

type StatusCode = 
    | OK          = 200
    | NoContent   = 204
    | MovedTemp   = 301
    | MovedPerm   = 302
    | SeeOther    = 303
    | NotModified = 304
    | NotFound    = 404
    | ServerError = 500

[<Literal>]
let NoBodyAllowedStatusCodes = [StatusCode.NoContent; StatusCode.NotModified]

我得到一个编译时错误,上面写着:

这不是有效的常量表达式或自定义属性值

我真的不知道这里出了什么问题。

【问题讨论】:

    标签: f# compile-time-constant constant-expression


    【解决方案1】:

    在 F# 和一般的 .NET 中,列表不能是文字(在 C#/VB.NET 中是常量)。只有原始值可以,例如 stringbool 等。F# 3.0 规范在第 10.2.2 节中有关于什么可以是文字的指南:

    具有 Literal 属性的值受以下限制:

    • 它可能没有被标记为可变或内联。
    • 它可能没有 ThreadStatic 或 ContextStatic 属性。
    • 右侧的表达式必须是由以下任一组成的文字常量表达式:
    • 一个简单的常量表达式,除了 ()、本机整数文字、无符号本机整数文字、字节数组文字、BigInteger 文字和用户定义的数字文字。

    ——或——

    • 对另一个字面量的引用。

    根据您要执行的操作,如果在类中使用let 绑定,您可以将列表设为静态。如果它在模块中,我只需删除 Literal 属性,因为 let 绑定默认情况下是不可变的。

    【讨论】:

    • 您提供给 MSDN 的链接并不完全相关。那里列出了作为 F# 语法术语的可能文字类型的列表。这与在 CLI 中可以呈现为文字的内容并不完全相同。 CLI 文字(或常量)是存储在程序集元数据中的值,因此可用于引用程序集而无需执行任何代码。在链接中列出的类型中,您不能创建类型为 decimalbigintunativeintbyte[] 的 CLI 常量。另一方面,CLI 允许任何引用类型的 nulls 作为常量(在 F# 中,nulls 是被禁止的)。
    • @AndreyChernyakhovskiy 我编辑为包含 F# 规范中的相关部分。感谢您指出这一点。
    • 这方面的规范可以在ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf, §II.22.9 中找到。它非常难以阅读,并且缺乏关于所有这些 CLI 内容如何映射到 F# 语法(或 C#)的信息。很高兴找到一个简单的解释。
    • @AndreyChernyakhovskiy:在 F# 中禁止使用空值是不正确的(遗憾的是),实际上您可以使用空文字。无论如何,列表肯定不是你可以拥有文字的东西。
    • 如果你用[&lt;AllowNullLiteral&gt;]属性装饰你的类型是可能的。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    相关资源
    最近更新 更多