【问题标题】:How to create record with some local private functions in F#如何在 F# 中使用一些本地私有函数创建记录
【发布时间】:2010-12-06 14:00:04
【问题描述】:
type SQLConn =
    val mutable private connection  : string option

    member this.Connection
        with get() : string   = this.connection.Value
        and  set(v)           = this.connection           <- Some v

    new (connection : string) = {connection = Some connection;}
    new() = SQLConn @"Data Source=D:\Projects\AL\Service\ncFlow\dbase\dbflow.db3; Version=3;Password=432432434324"

我想在那里使用“let x = 5+5”或类似的东西,所以我如何在我的类型(类)(记录)中使用私有函数,我知道如果我执行 SQLConn( ) ,但是我不能使用 val,我想同时使用 : val 和 let ...

谢谢

【问题讨论】:

  • 为了它的价值,惯用的 F# 避免(或至少最小化)使用 val

标签: f#


【解决方案1】:

正如 Tim 所解释的,您只能使用具有隐式构造函数语法的本地 let 绑定。我肯定会采用这种方法,因为它使 F# 代码更具可读性。

您有什么特别的原因要在代码中使用val 吗?您仍然可以将它们与隐式构造函数语法一起使用,但它们必须是可变的并使用突变进行初始化:

type SQLConn(connection:string) as x = 
  let mutable connection = connection

  // Declare field using 'val' declaration (has to be mutable)
  [<DefaultValue>]
  val mutable a : int 

  // Initialize the value imperatively in constructor
  do x.a <- 10

  member this.Connection 
    with get() = connection and set(v) = connection <- v 

  new() = SQLConn @"Data Source=.." 

据我所知,val 仅用于创建非私有字段(某些基于代码生成的工具可能需要,如 ASP.NET,但在其他方面并没有真正的用处)。

【讨论】:

  • @Tomas: val 也需要创建可用于静态成员和相同类型的其他实例的私有字段:stackoverflow.com/questions/3098942/…
  • @Tomas:如果您需要没有自动属性的良好 ol' 结构字段,还需要 val mutable
  • 另一个问题,connection 用作参数和局部变量名称,如果它的值来自 SQLConns 方法之一,或者它是否应该被命名为 let mutable _connection = connection,有没有办法访问这两者?
  • @Stephen:好点子——虽然这可以通过使用私有属性来解决,所以它不是严格需要的(不像val,例如ASP.NET)。 @Stringer:我认为let mutable 也会创建标准字段(没有属性)。
  • @gradbot:无法访问原始值。我故意使用相同的名称,以便可变值隐藏构造函数参数(事实上,当您想要可变字段的值时,您不会意外访问原始值)
【解决方案2】:

错误信息说明了问题:

错误 FS0963:除非使用隐式构造序列,否则类定义中不允许使用“let”和“do”绑定。您可以通过修改类型声明以包含参数来使用隐式构造序列,例如'类型 X(args) = ...'。

错误消息建议您将类声明为type SQLConn(connection) =。如果您这样做,您可能应该删除 member this.Connection 属性,因为您将不再拥有可变字段。

更可能的解决方法是将 x 声明为 val x : int,然后将 x = 5 + 5; 初始化器放入构造函数中。

【讨论】:

    【解决方案3】:

    接下来呢?

    type SQLConn(conn:string) =
      // could put some other let bindings here... 
      // ex: 'let y = 5 + 5' or whatever
      let mutable conn = conn
      new() = SQLConn(@"some default string")
      member __.Connection 
        with get () = conn and set v = conn <- v
    

    【讨论】:

      猜你喜欢
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2015-02-10
      相关资源
      最近更新 更多