Почему делает Hash.new ({}), скрывают участников хеша? [дубликат]

Это - лучшая практика никогда для использования бросков C-стиля по трем главным причинам:

  • , как уже упомянуто, никакая проверка не выполняется здесь. Программист просто не может знать, кто из различных бросков используется, который ослабляет строгий контроль типов
  • , новые броски намеренно визуально поразительны. Так как броски часто проявляют слабость в коде, утверждается, что создание бросков, видимых в коде, является хорошей вещью.
  • это особенно верно при поиске бросков с автоматизированным инструментом. Нахождение бросков C-стиля надежно почти невозможно.

, Поскольку palm3D отметил:

я нахожу синтаксис броска в стиле С++ слишком подробным.

Это является намеренным по причинам, приведенным выше.

синтаксис конструктора (официальное название: бросок функционального стиля), семантически тот же как бросок C-стиля и должен избежаться также (за исключением переменных инициализаций на объявлении), по тем же причинам. Это спорно, должно ли это быть верно даже для типов, которые определяют пользовательских конструкторов, но в Эффективном C++, Meyers утверждает, что даже в тех случаях необходимо воздержаться от использования их. Проиллюстрировать:

void f(auto_ptr<int> x);

f(static_cast<auto_ptr<int> >(new int(5))); // GOOD
f(auto_ptr<int>(new int(5));                // BAD

static_cast здесь будет на самом деле звонить auto_ptr конструктор.

12
задан Mladen Jablanović 30 November 2009 в 20:10
поделиться

1 ответ

It is expected behaviour (across all ruby versions). And if you experiment a bit further, you'll see that you always access the same hash, no matter which key you use:

>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}

The way Hash.new with a default argument works is: If you do hash[key] it checks whether that key exists in the hash. If it does, it returns the value for that key. If not it returns the default value. It does not add the key to the hash and it will return the same default object (not a copy) every time.

To get what you want, you want to specify a default block instead. That way, the block will be executed every time you access a key that is not in the hash. Inside the block you can create a new Hash and set the key to "point" to that hash. Like so:

Hash.new { |h,k|  h[k] = {} }
17
ответ дан 2 December 2019 в 19:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: