将字典键添加到F#中的构造函数

时间:2011-07-10 21:12:59

标签: f# dictionary

就像我对F#的新手一样,这似乎是某种基本问题。但是这里。我有一个使用以下代码的构造函数的类:

new () = { 
    _index = 0; _inputString = ""; 
    _tokens = new Dictionary<string, string>() {
        {"key", "value"}
    }
}

一切正常,除了F#似乎不允许我在我的字典中添加标记。我可以使用新的Dictionary&lt;&gt;初始化它对象,但如果我尝试填充,它会抛出一个错误。我也无法使用.Add成员。我见过F#构造函数初始化字段值的例子,但是没有办法执行其他代码吗?

3 个答案:

答案 0 :(得分:5)

由于Dictionarya constructor taking an IDictionary instance,您可以使用内置的dict功能来帮助您:

open System.Collections.Generic

type Foo =
    val _index       : int
    val _inputString : string
    val _tokens      : Dictionary<string, string>
    new () =
        {
            _index = 0
            _inputString = ""
            _tokens = Dictionary(dict [("fooKey", "fooValue")])
        }

但是,也可以在构造函数的对象初始值设定项之前或之后执行非平凡的代码:

type Bar =
    val _index       : int
    val _inputString : string
    val _tokens      : Dictionary<string, string>
    new () =
        let tokens = Dictionary()
        tokens.Add ("barKey", "barValue")
        {
            _index = 0
            _inputString = ""
            _tokens = tokens
        }

type Baz =
    val _index       : int
    val _inputString : string
    val _tokens      : Dictionary<string, string>
    new () as this =
        {
            _index = 0
            _inputString = ""
            _tokens = Dictionary()
        } then
        this._tokens.Add ("bazKey", "bazValue")

答案 1 :(得分:5)

Ildjarn已经回答了你的问题,但是我只想添加一个关于编码风格的说明 - 我认为现在大多数F#程序更喜欢隐式构造函数语法,你可以在其中定义一个隐式构造函数type声明的一部分。这通常使代码更简单。你可以这样写:

type Bah() = 
  let index = 0
  let inputString = ""
  let tokens = new Dictionary<string, string>()
  do tokens.Add("bazKey", "barValue")

  member x.Foo = "!"

这定义了无参数构造函数和私有字段(例如index)。在您的示例中,这没有多大意义(因为所有字段都是不可变的,因此index将始终为零)。我想你可能有其他的构造函数,在这种情况下你可以编写类似的东西:

type Baf(index:int, inputString:string, tokens:Dictionary<string, string>) =
  new() = 
    let tokens = new Dictionary<string, string>()
    tokens.Add("bazKey", "barValue")
    Baf(0, "", tokens)

在这里,你得到两个构造函数 - 一个参数少,一个带三个参数。您还可以将隐式构造函数设为私有,并仅公开更具体的情况:

type Baf private (index:int, inputString:string, tokens:Dictionary<string, string>) =
  // (...)

作为旁注,我还将命名从_index更改为index,因为我不认为F#指南建议使用下划线(尽管对于使用下划线声明的字段可能有意义val

答案 2 :(得分:3)

在F#中,所有内容都是表达式,因此您可以像这样初始化_tokens

open System.Collections.Generic
type Foo =
    val _index       : int
    val _inputString : string
    val _tokens      : Dictionary<string, string>
    new () =
        {
            _index = 0
            _inputString = ""
            _tokens = 
                let _tokens = Dictionary() 
                _tokens.Add ("key", "value") 
                _tokens
        }

轻量级语法可以让你想到让绑定和顺序表达式成为语句,但是如果我们写出这些表达式的完整详细语法,那就很清楚了:

...
_tokens = let _tokens = Dictionary() in _tokens.Add ("key", "value") ; _tokens
...