如何在F#中创建结构的新实例?

如何在F#中创建结构的新实例?,f#,F#,我对这一点感到非常愚蠢,但我很难找到关于这一点的文档 如果我这样声明一个结构: type BuildNumber = struct val major : int val minor : int val build : int val revision : int end 那么如何创建BuildNumber类型的新实例呢?您可以使用new关键字并为其定义构造函数 例如: type simple = st

我对这一点感到非常愚蠢,但我很难找到关于这一点的文档

如果我这样声明一个结构:

type BuildNumber = 
    struct
        val major : int
        val minor : int
        val build : int
        val revision : int
    end

那么如何创建
BuildNumber
类型的新实例呢?

您可以使用
new
关键字并为其定义构造函数

例如:

type simple = 
    struct
        val A : int
        val B : int
        new (a: int, b: int) = { A = a; B = b; }
    end

let s = new simple(1, 2)

如果定义中没有
new
,是否无法创建该类型的实例?如果是这样的话,它没用吗?@EricDand你仍然可以做
newsimple()
,它会工作得很好。但所有字段都将是该类型的默认值(在本例中为零),并且是不可变的。因此,不是100%无用,而是非常接近。如果您正在设计结构类型,需要注意的是,结构始终可以零初始化(即,使用“无参数构造函数”创建),而ref类型要么为null,要么必须经过实的、声明的构造函数。因此,如果向结构添加方法,请确保始终处理所有字段都为默认值的情况(此处理可能与引发无效的op异常一样简单)。@latkin:“结构始终可以零初始化”:几乎。。。除非某些字段是记录或联合,或者某些字段是不带[]属性的类或异常。在这些情况下,无法使用默认的无参数构造函数从F#实例化结构。(但它仍然可以从其他.NET语言中以这种方式实例化。)@latkin:感谢您对此进行进一步扩展。简而言之,只有在显式调用默认的无参数结构构造函数时,F#编译器才会对结构字段执行编译时初始化检查。在这种情况下,编译器报告错误FS0688:只有当结构类型的所有字段都允许默认初始化时,才能使用结构类型的默认零初始化构造函数。否则,不会执行编译时检查。因此,为了安全起见,on必须在结构中实现自定义运行时检查。请注意,在F#中,结构很少是一个好主意,最好使用记录。感谢您的提示!什么使记录更好?结构在F#中的作用与在C#中的作用完全相同——将数据保存在堆栈上,以便进行对时间敏感的数字运算。但是,一些有用的F#习惯用法和数据结构可能会导致数据无意中被放在堆上,这种低级优化在像F#这样的高级函数式语言中不太常见。此外,如果出于性能原因而不使用结构,则F#记录更易于处理。@EricDand:Records为您提供了与C#中的stuct相同的值类型语义(结构相等,不变性),并且它们完全集成在语言中(因此您有很好的语法来创建记录和在记录上进行模式匹配)。而结构是一个“外来”概念,使用起来很麻烦。