成员与类的F#记录

San*_*nti 2 f#

在F#中,您可以使用成员函数定义记录,也可以创建类。

type Album = {
    Id: int
    Name: string
    DateReleased: DateTime
    Genre: Genre }
with
    member this.PrintMessage() =
        printf "Hello from %s\n" this.Name
Run Code Online (Sandbox Code Playgroud)

这么用

let first = 
        { Id = 1; 
          Name = "Hello World!"
          Genre = KPop;
          DateReleased = DateTime(1991, 8, 12) }
first.PrintMessage()
Run Code Online (Sandbox Code Playgroud)

与类可能是这样的。

type Album(
     Id: int, 
     Name: string, 
     DateReleased: DateTime, 
     Genre: Genre ) as me =
     do
         me.PrintMessage()
     member this.PrintMessage() =
         printf "Hello %s" Name
Run Code Online (Sandbox Code Playgroud)

什么时候方便使用另一个?只能对记录进行域建模吗?

是否可以通过某些隐藏的FSharp Casting将类转换为记录,反之亦然?

Vor*_*ato 5

可以使用记录和类来完成领域建模。我认为何时使用其中一个主要取决于偏好和环境。我个人通常不使用类,但是我知道有些人经常使用它们。类更多地依赖于突变,并且在易于使用的代价下性能更高。我个人认为,如果要编写面向对象的样式,请使用类;如果要编写功能样式,请使用记录。记录模式匹配和解构更加容易。这种区别的一部分是文化上的,仅仅是因为您可以以特定的方式做某事,并不意味着其他人就能轻松地理解您。代码被编写为供您自己和他人阅读。当您选择记录或类时,它传达有关这些类型的样式和用法的意图。最后,我不知道一个类可以在F#中转换为记录,如果可以的话,我实际上仍然建议不要这样做。这是因为将记录用作类,将类用作记录与这些构造的文化规范相冲突。我个人认为您的示例成员适用于记录和类。我通常喜欢对与给定类型关联的函数使用具有相同名称的模块,因为当函数碰巧消耗除记录类型之外的其他东西时,它可以减少混乱。但是,我认为任何有风度的人都不会对那里的任何代码示例感到厌烦。这是因为将记录用作类,将类用作记录与这些构造的文化规范相冲突。我个人认为您的示例成员适用于记录和类。我通常喜欢对与给定类型关联的函数使用具有相同名称的模块,因为当函数碰巧消耗除记录类型之外的其他东西时,它可以减少混乱。但是,我认为任何有风度的人都不会对那里的任何代码示例感到厌烦。这是因为将记录用作类,将类用作记录与这些构造的文化规范相冲突。我个人认为您的示例成员适用于记录和类。我通常喜欢对与给定类型关联的函数使用具有相同名称的模块,因为当函数碰巧消耗除记录类型之外的其他东西时,它可以减少混乱。但是,我认为任何有风度的人都不会对那里的任何代码示例感到厌烦。

type Album(
    Id: int, 
    Name: string, 
    DateReleased: string, 
    Genre: int ) as me =
    let mutable genre = Genre  
    //readonly property
    member val Id = Id
    //autoproperty with get and set
    member val Name = Name with get, set
    member val DateReleased = DateReleased with get, set
    //property with explicit get and set
    member this.Genre 
        with get () = genre
        and set (value) = genre <- value
Run Code Online (Sandbox Code Playgroud)

请参阅何时应使用let,成员val和成员this。