【问题标题】:Multiple constructors and properties多个构造函数和属性
【发布时间】:2017-09-25 21:04:26
【问题描述】:

我的源代码出现下一个错误:

  1. “名称”没有值
  2. 您应该调用备用构造函数

那么,我如何在 F# 中下一节课呢?

type Person = class
    member val Name: string
    member val Age: int option = None

    new() = { Name = "Anonymous" }
    new(name) = { Name = name }
    new(name, age: int) = { Name = name; Age = age }

    static member Hello =
            printfn "Hello, %O" Name
    end

编辑

根据这篇文章中的@user2088029 答案和Object initializer + property initializer (from C# to F#) 中的@kvb 答案,我创建了下一个我想要的来源。 问题是“Person(name, Age = age)”表示 error 带有“Noaccessible member or object constructor named 'Person' 需要 1 个参数”。

type Person(name) = 
    member this.Name: string = name
    member this.Age: int option = None //with get,set

    new() = Person("Anonymous")
    new(name, age: int) = Person(name, Age = age)

    member this.Hello =
        printfn "Hello, %O" this.Name

用法:

let person = Person("Alex", Option = Some 25)

【问题讨论】:

    标签: f#


    【解决方案1】:
    type Person(name : string,age : int option) = 
       new() = Person("Anonymous")
       new(name) = Person(name,None)
       new(name, age: int) = Person(name, Some age)
       member this.Name : string       = name
       member this.Age : int option    = age
    
       member this.Hello() =
            printfn "Hello, %O" this.Name
    

    我不完全确定你想做什么,F# 不是我的第一语言,而且我可能不会编写这样的代码(我个人不喜欢多个构造函数)......但无论如何

    主构造函数放在类型名称之后。 那么你就不需要“class”和“end”

    主构造函数做了两件事

    I) 它定义了一个用于创建新对象/值的静态方法

    ii) 它定义了类的字段/属性

    然后你有其他的构造函数....

    我假设您希望 Name 和 Age 作为类 Person? 的实例方法?..因此它们需要以对象变量为前缀,“this”对于 OOers 来说似乎是一个合理的名称。

    你的静态方法不起作用,因为如果它是静态的,它没有代表一个人的变量,所以我将它实现为实例方法

    我不太清楚为什么存在“class/end”结构,我怀疑可能是因为您可以创建“struct/end”结构,而这些结构没有构造函数,但我几乎从未见过"class/end" 结构在教科书中描述语法的部分之外的任何地方使用。

    【讨论】:

    • 我可以避免主构造函数吗?我想要类型声明之后的构造函数。
    • a) 我不这么认为。
    • b) 你为什么在乎?
    • 我觉得更具可读性。然后,如果我不能,那么class..end有什么用? @user2088029
    • @user2088029: class/end 是所谓的verbose syntax 的产物,它以 OCaml 为模型。在代码中使用它是一种罕见的景象(因为轻量级语法很早就成为了默认语法),但今天当您在 F# 交互中评估类型时仍然可以看到它。
    【解决方案2】:

    修改后的代码sn-p,有两个问题:

    • 您的 Age 属性是只读的,因此它没有设置器
    • 您在构造函数中采用名称和年龄的初始化程序无效 - F# 中对构造函数的外观有相当严格的限制

    您可以通过使用get, set 将Age 转换为val 属性来修复前者,您可以通过使用(有点奇怪)调用基本构造函数的语法来修复后者,然后执行其他操作。以下作品:

    type Person(name) = 
        member this.Name: string = name
        member val Age = None with get, set
    
        new() = Person("Anonymous")
        new(name, age: int) as this = Person(name) then this.Age <- Some age
    
        member this.Hello =
            printfn "Hello, %O" this.Name
    

    也就是说,@user2088029 的解决方案使具有两个参数的构造函数成为主要的构造函数要好得多,我建议改用它!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 2022-12-16
      • 1970-01-01
      相关资源
      最近更新 更多