Добавление словарного ключа к конструктору в F # - PullRequest
1 голос
/ 11 июля 2011

То, что я новичок в F #, может показаться чем-то вроде элементарного вопроса. Но здесь идет. У меня есть класс с конструктором, используя следующий код:

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

Все работает, кроме F #, кажется, не позволяет мне добавлять токены в мой словарь. Я могу инициализировать его новым объектом Dictionary <>, но если я попытаюсь заполнить его, он выдаст ошибку. Я также не могу сделать это с членом .Добавить. Я видел примеры конструкторов F #, инициализирующих значения полей, но нет ли способа выполнить другой код, может быть?

Ответы [ 3 ]

5 голосов
/ 11 июля 2011

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)

5 голосов
/ 11 июля 2011

Поскольку Dictionary имеет конструктор, принимающий IDictionary экземпляр , вы можете использовать встроенную функцию 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")
3 голосов
/ 11 июля 2011

В 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
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...