F#int.MaxValue是"不是有效的常量表达式",但System.Int32.MaxValue是?

  发布于 2023-02-14 01:22

TL; DR: F#编译器解释int在这种情况下为int操作者,如由Eugene Fotin确定和通过基因Belitski时膨胀.最佳解决方法是使用System.Int32.MaxValue或如下所述的唯一类型别名.


请考虑以下记录类型:

type User = {
    Username : string
}

我想要Username至少三个字符,所以我使用该StringLength属性.没有最大长度,所以我将它设置为int.MaxValue:

type User = {
    []
    Username : string
}

这给了我以下错误:

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

如果我使用的话,一切都是桃子的System.Int32:

type User = {
    []
    Username : string
}

如果我别名它也会编译int:

type User = {
    []
    Username : string
}
and num = int

或完全符合类型:

type User = {
    []
    Username : string
}

我检查了F#源代码,并且int完全按照您的预期定义:

type int32 = System.Int32
// Then, a few lines later…
type int = int32

这是怎么回事?我假设F#原始类型在大多数情况下都可与其他类型互换,但看起来我的心理模型中缺少某些东西.

2 个回答
  • 看起来编译器将int属性的参数视为转换函数int.

    2023-02-14 01:38 回答
  • 这就是F#类型推断如何在不同的语境中工作,其中不同的语法实体巧合地具有相同的名称,在以下情况中int可以是以下任何一种:

    int:'T->int全名功能Microsoft.FSharp.Core.Operators.int

    type int = int32 全名 Microsoft.FSharp.Core.int

    type int<'Measure> = int 全名 Microsoft.FSharp.Core.int<_>

    演示此工作的一种方法是以下场景:如果我们只是输入

    int;;
    

    在FSI,我们会得到类似的东西

    val it : (int -> int) = <fun:it@3>
    

    换句话说,它是一个不能具有MaxValue与之关联的属性的函数:

    > int.MaxValue;;
    
    int.MaxValue;;
    ----^^^^^^^^
    
    ... error FS0039: The field, constructor or member 'MaxValue' is not defined
    

    同样适用于int32,当在表达的上下文中使用时,由FSI推断为具有签名的另一个函数(int -> int32).

    现在说到了

    type num = int
    

    在这个上下文中int被推断为类型名称的缩写System.Int32,因此num也是类型缩写,但现在名称歧义没有位置,因此num.MaxValue推断出我们期望它的确切含义,在FSI中给出

    > num.MaxValue;;
    val it : int = 2147483647
    

    最后,当您使用Microsoft.FSharp.Core.int显式引用类型实体时,没有模糊性的地方,因此它按预期工作.

    回到带有属性参数的用例 - 在此上下文int中,类型推断将其作为表达式的一部分来处理,以传递参数值,即作为函数,除非您明确或间接设置另一个解释.

    2023-02-14 01:42 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有